diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile index 0a0acf9..7b6d404 100644 --- a/.gitpod.Dockerfile +++ b/.gitpod.Dockerfile @@ -5,4 +5,5 @@ RUN sudo apt-get install -y libappindicator1 fonts-liberation RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb RUN sudo dpkg -i google-chrome*.deb; return 0; RUN sudo apt-get install -y -f -RUN sudo dpkg -i google-chrome*.deb \ No newline at end of file +RUN sudo dpkg -i google-chrome*.deb +RUN sudo curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sudo sh -s -- -b $(go env GOPATH)/bin \ No newline at end of file diff --git a/.gitpod.yml b/.gitpod.yml index 2b3c1ba..5d977e9 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -14,6 +14,8 @@ tasks: -e POSTGRES_USER=netsepio \ -e POSTGRES_DB=netsepio \ postgres -c log_statement=all + cp .env-sample .env + air vscode: extensions: - golang.go diff --git a/README.md b/README.md index e78fd9e..e19d5a1 100644 --- a/README.md +++ b/README.md @@ -98,3 +98,11 @@ Note - Some unset data is emitted. | :------------ | :--------------------- | | `voter` | **Required**. `string` | | `MetaDataUri` | **Required**. `string` | + +``` + POST /feedback +``` + +| Parameter | Type | +| :--------- | :--------------------- | +| `feedback` | **Required**. `string` | diff --git a/api/v1/feedback/feedback.go b/api/v1/feedback/feedback.go new file mode 100644 index 0000000..5c900d3 --- /dev/null +++ b/api/v1/feedback/feedback.go @@ -0,0 +1,49 @@ +package feedback + +import ( + "net/http" + + "github.com/NetSepio/gateway/api/middleware/auth/paseto" + "github.com/NetSepio/gateway/config/dbconfig" + "github.com/NetSepio/gateway/models" + "github.com/NetSepio/gateway/util/pkg/httphelper" + "github.com/jinzhu/gorm" + "github.com/lib/pq" + + "github.com/gin-gonic/gin" +) + +// ApplyRoutes applies router to gin Router +func ApplyRoutes(r *gin.RouterGroup) { + g := r.Group("/feedback") + { + g.Use(paseto.PASETO) + g.POST("", createFeedback) + } +} + +func createFeedback(c *gin.Context) { + db := dbconfig.GetDb() + var requestBody PostFeedbackRequest + err := c.BindJSON(&requestBody) + if err != nil { + return + } + walletAddress := c.GetString("walletAddress") + + result := db.Model(&models.User{}).Where("wallet_address = ?", walletAddress). + Update("feedbacks", gorm.Expr("feedbacks || ?", pq.StringArray([]string{requestBody.Feedback}))) + + if result.Error != nil { + httphelper.ErrResponse(c, http.StatusInternalServerError, "Unexpected error occured") + + return + } + if result.RowsAffected == 0 { + httphelper.ErrResponse(c, http.StatusNotFound, "Record not found") + + return + } + httphelper.SuccessResponse(c, "Feedback added", nil) + +} diff --git a/api/v1/feedback/feedback_test.go b/api/v1/feedback/feedback_test.go new file mode 100644 index 0000000..fb1ce95 --- /dev/null +++ b/api/v1/feedback/feedback_test.go @@ -0,0 +1,49 @@ +package feedback + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/NetSepio/gateway/config" + "github.com/NetSepio/gateway/util/pkg/logwrapper" + "github.com/NetSepio/gateway/util/testingcommon" + + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" +) + +func Test_PostFeedback(t *testing.T) { + config.Init("../../../.env") + logwrapper.Init("../../../logs") + t.Cleanup(testingcommon.DeleteCreatedEntities()) + testWallet := testingcommon.GenerateWallet() + header := testingcommon.PrepareAndGetAuthHeader(t, testWallet.WalletAddress) + + url := "/api/v1.0/feedback" + + t.Run("Should be able to add feedback", func(t *testing.T) { + rr := httptest.NewRecorder() + + requestBody := PostFeedbackRequest{ + Feedback: "Very helpfull for avoiding spam and harmfull domains", + } + jsonData, err := json.Marshal(requestBody) + if err != nil { + t.Fatal(err) + } + req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) + req.Header.Add("Authorization", header) + if err != nil { + t.Fatal(err) + } + c, _ := gin.CreateTestContext(rr) + c.Request = req + c.Set("walletAddress", testWallet.WalletAddress) + + createFeedback(c) + assert.Equal(t, http.StatusOK, rr.Result().StatusCode) + }) +} diff --git a/api/v1/feedback/types.go b/api/v1/feedback/types.go new file mode 100644 index 0000000..9461084 --- /dev/null +++ b/api/v1/feedback/types.go @@ -0,0 +1,5 @@ +package feedback + +type PostFeedbackRequest struct { + Feedback string `json:"feedback" binding:"required"` +} diff --git a/api/v1/v1.go b/api/v1/v1.go index 651ce39..c6f8ef4 100644 --- a/api/v1/v1.go +++ b/api/v1/v1.go @@ -4,6 +4,7 @@ import ( authenticate "github.com/NetSepio/gateway/api/v1/authenticate" claimrole "github.com/NetSepio/gateway/api/v1/claimRole" delegatereviewcreation "github.com/NetSepio/gateway/api/v1/delegateReviewCreation" + "github.com/NetSepio/gateway/api/v1/feedback" flowid "github.com/NetSepio/gateway/api/v1/flowid" "github.com/NetSepio/gateway/api/v1/healthcheck" "github.com/NetSepio/gateway/api/v1/profile" @@ -23,5 +24,6 @@ func ApplyRoutes(r *gin.RouterGroup) { claimrole.ApplyRoutes(v1) delegatereviewcreation.ApplyRoutes(v1) healthcheck.ApplyRoutes(v1) + feedback.ApplyRoutes(v1) } } diff --git a/models/User.go b/models/User.go index a39b028..eabb1f3 100644 --- a/models/User.go +++ b/models/User.go @@ -1,9 +1,12 @@ package models +import "github.com/lib/pq" + type User struct { - Name string `json:"name,omitempty"` - WalletAddress string `gorm:"primary_key" json:"walletAddress"` - FlowIds []FlowId `gorm:"foreignkey:WalletAddress" json:"-"` - ProfilePictureUrl string `json:"profilePictureUrl,omitempty"` - Country string `json:"country,omitempty"` + Name string `json:"name,omitempty"` + WalletAddress string `gorm:"primary_key" json:"walletAddress"` + FlowIds []FlowId `gorm:"foreignkey:WalletAddress" json:"-"` + ProfilePictureUrl string `json:"profilePictureUrl,omitempty"` + Country string `json:"country,omitempty"` + Feedbacks pq.StringArray `json:"-" gorm:"type:text[]"` }