add comment update (edit once)
This commit is contained in:
@@ -89,6 +89,7 @@ func (s *Server) Run() {
|
||||
// protected routes, require auth
|
||||
rapi.With(auth.Auth(s.SessionStore, s.Admins, maybeDevMode(auth.Full))).Group(func(rauth chi.Router) {
|
||||
rauth.Post("/comment", s.createCommentCtrl)
|
||||
rauth.Put("/comment/{id}", s.updateCommentCtrl)
|
||||
rauth.Get("/user", s.userInfoCtrl)
|
||||
rauth.Put("/vote/{id}", s.voteCtrl)
|
||||
|
||||
@@ -148,6 +149,50 @@ func (s *Server) createCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, JSON{"id": id, "loc": comment.Locator})
|
||||
}
|
||||
|
||||
// PUT /comment/{id}?site=siteID&url=post-url - update comment
|
||||
func (s *Server) updateCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
edit := struct {
|
||||
Text string
|
||||
Summary string
|
||||
}{}
|
||||
|
||||
if err := render.DecodeJSON(r.Body, &edit); err != nil {
|
||||
common.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't bind comment")
|
||||
return
|
||||
}
|
||||
|
||||
user, err := common.GetUserInfo(r)
|
||||
if err != nil { // this not suppose to happen (handled by Auth), just dbl-check
|
||||
common.SendErrorJSON(w, r, http.StatusUnauthorized, err, "can't get user info")
|
||||
return
|
||||
}
|
||||
locator := store.Locator{SiteID: r.URL.Query().Get("site"), URL: r.URL.Query().Get("url")}
|
||||
id := chi.URLParam(r, "id")
|
||||
log.Printf("[DEBUG] update comment %s, %+v", id, edit)
|
||||
|
||||
var currComment store.Comment
|
||||
if currComment, err = s.DataService.Get(locator, id); err != nil {
|
||||
common.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't find comment")
|
||||
return
|
||||
}
|
||||
|
||||
if currComment.User.ID != user.ID {
|
||||
common.SendErrorJSON(w, r, http.StatusForbidden, errors.New("rejected"), "can not edit comments for other users")
|
||||
return
|
||||
}
|
||||
|
||||
res, err := s.DataService.EditComment(locator, id, edit.Text, store.Edit{Summary: edit.Summary})
|
||||
if err != nil {
|
||||
common.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't update comment")
|
||||
return
|
||||
}
|
||||
|
||||
s.respCache.Flush() // reset all caches
|
||||
|
||||
render.JSON(w, r, JSON{"id": id, "loc": locator, "comment": res})
|
||||
}
|
||||
|
||||
// DELETE /comment/{id}?site=siteID&url=post-url
|
||||
func (s *Server) deleteCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
|
||||
@@ -11,9 +11,8 @@ import (
|
||||
var testDb = "/tmp/test-remark.db"
|
||||
|
||||
func TestBoltDB_CreateAndFind(t *testing.T) {
|
||||
var b Interface
|
||||
var b Interface = prep(t)
|
||||
defer os.Remove(testDb)
|
||||
b = prep(t)
|
||||
|
||||
res, err := b.Find(Request{Locator: Locator{URL: "https://radio-t.com", SiteID: "radio-t"}})
|
||||
assert.Nil(t, err)
|
||||
|
||||
+24
-1
@@ -1,6 +1,10 @@
|
||||
package store
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Service wraps store.Interface with additional methods
|
||||
type Service struct {
|
||||
@@ -39,3 +43,22 @@ func (s *Service) Vote(locator Locator, commentID string, userID string, val boo
|
||||
|
||||
return comment, s.Put(locator, comment)
|
||||
}
|
||||
|
||||
// EditComment to edit text and update Edit info
|
||||
func (s *Service) EditComment(locator Locator, commentID string, text string, edit Edit) (comment Comment, err error) {
|
||||
comment, err = s.Get(locator, commentID)
|
||||
if err != nil {
|
||||
return comment, err
|
||||
}
|
||||
// edit allowed only once
|
||||
if !comment.Edit.Timestamp.IsZero() {
|
||||
return comment, errors.Errorf("comment %s already edited at %s", commentID, comment.Edit.Timestamp)
|
||||
}
|
||||
|
||||
comment.Text = text
|
||||
comment.Edit = edit
|
||||
comment.Edit.Timestamp = time.Now()
|
||||
comment = sanitizeComment(comment)
|
||||
err = s.Put(locator, comment)
|
||||
return comment, err
|
||||
}
|
||||
|
||||
@@ -55,3 +55,24 @@ func TestBoltDB_Pin(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, false, c.Pin)
|
||||
}
|
||||
|
||||
func TestBoltDB_EditComment(t *testing.T) {
|
||||
defer os.Remove(testDb)
|
||||
b := Service{Interface: prep(t)}
|
||||
|
||||
res, err := b.Last(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, 0)
|
||||
t.Logf("%+v", res[0])
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(res))
|
||||
assert.Equal(t, Edit{}, res[0].Edit)
|
||||
|
||||
comment, err := b.EditComment(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID, "xxx", Edit{Summary: "my edit"})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "my edit", comment.Edit.Summary)
|
||||
assert.Equal(t, "xxx", comment.Text)
|
||||
|
||||
c, err := b.GetByID(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "my edit", c.Edit.Summary)
|
||||
assert.Equal(t, "xxx", c.Text)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ type Comment struct {
|
||||
Votes map[string]bool `json:"votes"`
|
||||
Timestamp time.Time `json:"time"`
|
||||
Pin bool `json:"pin,omitempty"`
|
||||
Edit Edit `json:"edit,omitempty"`
|
||||
}
|
||||
|
||||
// Locator keeps site and url of the post
|
||||
@@ -44,6 +45,12 @@ type User struct {
|
||||
IP string `json:"-"`
|
||||
}
|
||||
|
||||
// Edit indication
|
||||
type Edit struct {
|
||||
Timestamp time.Time `json:"time"`
|
||||
Summary string `json:"summary"`
|
||||
}
|
||||
|
||||
// Request is a container for all finds
|
||||
type Request struct {
|
||||
Locator Locator `json:"locator"`
|
||||
|
||||
+12
@@ -25,6 +25,15 @@ Content-Type: application/json
|
||||
}
|
||||
}
|
||||
|
||||
### update comment
|
||||
POST https://demo.remark42.com/api/v1/comment/a2ddb8d2f65008ee1a1e3af8df0f26beb042309c?site=remark&url=https://radio-t.com/blah1
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"text": "edit comment blah http://radio-t.com 12345",
|
||||
"summary": "fix blah"
|
||||
}
|
||||
|
||||
### pin comment
|
||||
PUT https://demo.remark42.com/api/v1/admin/pin/3665976683?site=remark&url=https://radio-t.com/p/2017/12/16/podcast-576/&pin=1
|
||||
|
||||
@@ -37,6 +46,9 @@ GET https://demo.remark42.com/api/v1/user
|
||||
### get comment by id
|
||||
GET https://demo.remark42.com/api/v1/id/3665976683?site=remark&url=https://radio-t.com/p/2017/12/16/podcast-576/
|
||||
|
||||
### get comment by id 2
|
||||
GET https://demo.remark42.com/api/v1/id/a2ddb8d2f65008ee1a1e3af8df0f26beb042309c?site=remark&url=https://radio-t.com/blah1
|
||||
|
||||
### get comment by user id
|
||||
GET https://demo.remark42.com/api/v1/comments?site=remark&user=umputun
|
||||
|
||||
|
||||
Reference in New Issue
Block a user