change remote interface to struct requests

This commit is contained in:
Umputun
2019-06-25 20:06:30 -05:00
parent bab09effa2
commit 988206bed4
8 changed files with 139 additions and 99 deletions
+13 -11
View File
@@ -137,19 +137,19 @@ func (b *BoltDB) Create(comment store.Comment) (commentID string, err error) {
}
// Get returns comment for locator.URL and commentID string
func (b *BoltDB) Get(locator store.Locator, commentID string) (comment store.Comment, err error) {
func (b *BoltDB) Get(req GetRequest) (comment store.Comment, err error) {
bdb, err := b.db(locator.SiteID)
bdb, err := b.db(req.Locator.SiteID)
if err != nil {
return comment, err
}
err = bdb.View(func(tx *bolt.Tx) error {
bucket, e := b.getPostBucket(tx, locator.URL)
bucket, e := b.getPostBucket(tx, req.Locator.URL)
if e != nil {
return e
}
return b.load(bucket, commentID, &comment)
return b.load(bucket, req.CommentID, &comment)
})
return comment, err
}
@@ -204,9 +204,10 @@ func (b *BoltDB) Flag(req FlagRequest) (val bool, err error) {
}
// Update for locator.URL with mutable part of comment
func (b *BoltDB) Update(locator store.Locator, comment store.Comment) error {
func (b *BoltDB) Update(comment store.Comment) error {
if curComment, err := b.Get(locator, comment.ID); err == nil {
getReq := GetRequest{Locator: comment.Locator, CommentID: comment.ID}
if curComment, err := b.Get(getReq); err == nil {
// preserve immutable fields
comment.ParentID = curComment.ParentID
comment.Locator = curComment.Locator
@@ -214,13 +215,13 @@ func (b *BoltDB) Update(locator store.Locator, comment store.Comment) error {
comment.User = curComment.User
}
bdb, err := b.db(locator.SiteID)
bdb, err := b.db(comment.Locator.SiteID)
if err != nil {
return err
}
return bdb.Update(func(tx *bolt.Tx) error {
bucket, e := b.getPostBucket(tx, locator.URL)
bucket, e := b.getPostBucket(tx, comment.Locator.URL)
if e != nil {
return e
}
@@ -351,8 +352,8 @@ func (b *BoltDB) ListFlags(req FlagRequest) (res []interface{}, err error) {
if time.Now().Before(ts) {
// get user name from comment user section
userName := ""
req := FindRequest{Locator: store.Locator{SiteID: req.Locator.SiteID}, UserID: string(k), Limit: 1}
userComments, errUser := b.Find(req)
findReq := FindRequest{Locator: store.Locator{SiteID: req.Locator.SiteID}, UserID: string(k), Limit: 1}
userComments, errUser := b.Find(findReq)
if errUser == nil && len(userComments) > 0 {
userName = userComments[0].User.Name
}
@@ -500,7 +501,8 @@ func (b *BoltDB) userComments(siteID, userID string, limit, skip int) (comments
if errParse != nil {
return comments, errors.Wrapf(errParse, "can't parse reference %s", v)
}
if c, errRef := b.Get(store.Locator{SiteID: siteID, URL: url}, commentID); errRef == nil {
getReq := GetRequest{Locator: store.Locator{SiteID: siteID, URL: url}, CommentID: commentID}
if c, errRef := b.Get(getReq); errRef == nil {
comments = append(comments, c)
}
}
+21 -7
View File
@@ -19,6 +19,10 @@ func TestBoltDB_CreateAndFind(t *testing.T) {
var b, teardown = prep(t)
defer teardown()
var bb Interface
bb = b
_ = bb
req := FindRequest{Locator: store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, Sort: "time"}
res, err := b.Find(req)
assert.NoError(t, err)
@@ -77,14 +81,14 @@ func TestBoltDB_Get(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, 2, len(res), "2 records initially")
comment, err := b.Get(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[1].ID)
comment, err := b.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[1].ID))
assert.NoError(t, err)
assert.Equal(t, "some text2", comment.Text)
comment, err = b.Get(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, "1234567")
comment, err = b.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, "1234567"))
assert.NotNil(t, err)
_, err = b.Get(store.Locator{URL: "https://radio-t.com", SiteID: "bad"}, res[1].ID)
_, err = b.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "bad"}, res[1].ID))
assert.EqualError(t, err, `site "bad" not found`)
}
@@ -100,19 +104,22 @@ func TestBoltDB_Update(t *testing.T) {
comment := res[0]
comment.Text = "abc 123"
comment.Score = 100
err = b.Update(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, comment)
err = b.Update(comment)
assert.NoError(t, err)
comment, err = b.Get(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID)
comment, err = b.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID))
assert.NoError(t, err)
assert.Equal(t, "abc 123", comment.Text)
assert.Equal(t, res[0].ID, comment.ID)
assert.Equal(t, 100, comment.Score)
err = b.Update(store.Locator{URL: "https://radio-t.com", SiteID: "bad"}, comment)
comment.Locator.SiteID = "bad"
err = b.Update(comment)
assert.EqualError(t, err, `site "bad" not found`)
err = b.Update(store.Locator{URL: "https://radio-t.com-bad", SiteID: "radio-t"}, comment)
comment.Locator.SiteID="radio-t"
comment.Locator.URL="https://radio-t.com-bad"
err = b.Update(comment)
assert.EqualError(t, err, `no bucket https://radio-t.com-bad in store`)
}
@@ -806,3 +813,10 @@ func prep(t *testing.T) (b *BoltDB, teardown func()) {
}
return b, teardown
}
func getReq(locator store.Locator, commentID string) GetRequest {
return GetRequest{
Locator: locator,
CommentID: commentID,
}
}
+16 -10
View File
@@ -16,16 +16,22 @@ import (
// Interface defines methods provided by low-level storage engine
type Interface interface {
Create(comment store.Comment) (commentID string, err error) // create new comment, avoid dups by id
Update(locator store.Locator, comment store.Comment) error // update comment, mutable parts only
Get(locator store.Locator, commentID string) (store.Comment, error) // get comment by id
Find(req FindRequest) ([]store.Comment, error) // find comments for locator or site
Info(req InfoRequest) ([]store.PostInfo, error) // get post(s) meta info
Count(req FindRequest) (int, error) // get count for post or user
Delete(req DeleteRequest) error // delete post(s) by id or by userID
Flag(req FlagRequest) (bool, error) // set and get flags
ListFlags(req FlagRequest) ([]interface{}, error) // get list of flagged keys, like blocked & verified user
Close() error // close storage engine
Create(comment store.Comment) (commentID string, err error) // create new comment, avoid dups by id
Update(comment store.Comment) error // update comment, mutable parts only
Get(req GetRequest) (store.Comment, error) // get comment by id
Find(req FindRequest) ([]store.Comment, error) // find comments for locator or site
Info(req InfoRequest) ([]store.PostInfo, error) // get post(s) meta info
Count(req FindRequest) (int, error) // get count for post or user
Delete(req DeleteRequest) error // delete post(s) by id or by userID
Flag(req FlagRequest) (bool, error) // set and get flags
ListFlags(req FlagRequest) ([]interface{}, error) // get list of flagged keys, like blocked & verified user
Close() error // close storage engine
}
// GetRequest is the input for Get func
type GetRequest struct {
Locator store.Locator `json:"locator"`
CommentID string `json:"comment_id"`
}
// FindRequest is the input for all find operations
+12 -12
View File
@@ -123,20 +123,20 @@ func (_m *MockInterface) Flag(req FlagRequest) (bool, error) {
return r0, r1
}
// Get provides a mock function with given fields: locator, commentID
func (_m *MockInterface) Get(locator store.Locator, commentID string) (store.Comment, error) {
ret := _m.Called(locator, commentID)
// Get provides a mock function with given fields: req
func (_m *MockInterface) Get(req GetRequest) (store.Comment, error) {
ret := _m.Called(req)
var r0 store.Comment
if rf, ok := ret.Get(0).(func(store.Locator, string) store.Comment); ok {
r0 = rf(locator, commentID)
if rf, ok := ret.Get(0).(func(GetRequest) store.Comment); ok {
r0 = rf(req)
} else {
r0 = ret.Get(0).(store.Comment)
}
var r1 error
if rf, ok := ret.Get(1).(func(store.Locator, string) error); ok {
r1 = rf(locator, commentID)
if rf, ok := ret.Get(1).(func(GetRequest) error); ok {
r1 = rf(req)
} else {
r1 = ret.Error(1)
}
@@ -190,13 +190,13 @@ func (_m *MockInterface) ListFlags(req FlagRequest) ([]interface{}, error) {
return r0, r1
}
// Update provides a mock function with given fields: locator, comment
func (_m *MockInterface) Update(locator store.Locator, comment store.Comment) error {
ret := _m.Called(locator, comment)
// Update provides a mock function with given fields: comment
func (_m *MockInterface) Update(comment store.Comment) error {
ret := _m.Called(comment)
var r0 error
if rf, ok := ret.Get(0).(func(store.Locator, store.Comment) error); ok {
r0 = rf(locator, comment)
if rf, ok := ret.Get(0).(func(store.Comment) error); ok {
r0 = rf(comment)
} else {
r0 = ret.Error(0)
}
+12 -12
View File
@@ -15,7 +15,7 @@ type Remote struct {
// Create comment and return ID
func (r *Remote) Create(comment store.Comment) (commentID string, err error) {
resp, err := r.Call("create", comment)
resp, err := r.Call("store.create", comment)
if err != nil {
return "", err
}
@@ -25,8 +25,8 @@ func (r *Remote) Create(comment store.Comment) (commentID string, err error) {
}
// Get comment by ID
func (r *Remote) Get(locator store.Locator, commentID string) (comment store.Comment, err error) {
resp, err := r.Call("get", locator, commentID)
func (r *Remote) Get(req GetRequest) (comment store.Comment, err error) {
resp, err := r.Call("store.get", req)
if err != nil {
return store.Comment{}, err
}
@@ -36,14 +36,14 @@ func (r *Remote) Get(locator store.Locator, commentID string) (comment store.Com
}
// Update comment, mutable parts only
func (r *Remote) Update(locator store.Locator, comment store.Comment) error {
_, err := r.Call("update", locator, comment)
func (r *Remote) Update(comment store.Comment) error {
_, err := r.Call("store.update", comment)
return err
}
// Find comments for locator
func (r *Remote) Find(req FindRequest) (comments []store.Comment, err error) {
resp, err := r.Call("find", req)
resp, err := r.Call("store.find", req)
if err != nil {
return nil, err
}
@@ -53,7 +53,7 @@ func (r *Remote) Find(req FindRequest) (comments []store.Comment, err error) {
// Info returns post(s) meta info
func (r *Remote) Info(req InfoRequest) (info []store.PostInfo, err error) {
resp, err := r.Call("info", req)
resp, err := r.Call("store.info", req)
if err != nil {
return nil, err
}
@@ -63,7 +63,7 @@ func (r *Remote) Info(req InfoRequest) (info []store.PostInfo, err error) {
// Flag sets and gets flags
func (r *Remote) Flag(req FlagRequest) (status bool, err error) {
resp, err := r.Call("flag", req)
resp, err := r.Call("store.flag", req)
if err != nil {
return false, err
}
@@ -73,7 +73,7 @@ func (r *Remote) Flag(req FlagRequest) (status bool, err error) {
// ListFlags get list of flagged keys, like blocked & verified user
func (r *Remote) ListFlags(req FlagRequest) (list []interface{}, err error) {
resp, err := r.Call("list_flags", req)
resp, err := r.Call("store.list_flags", req)
if err != nil {
return nil, err
}
@@ -83,7 +83,7 @@ func (r *Remote) ListFlags(req FlagRequest) (list []interface{}, err error) {
// Count gets comments count by user or site
func (r *Remote) Count(req FindRequest) (count int, err error) {
resp, err := r.Call("count", req)
resp, err := r.Call("store.count", req)
if err != nil {
return 0, err
}
@@ -93,12 +93,12 @@ func (r *Remote) Count(req FindRequest) (count int, err error) {
// Delete post(s) by id or by userID
func (r *Remote) Delete(req DeleteRequest) error {
_, err := r.Call("delete", req)
_, err := r.Call("store.delete", req)
return err
}
// Close storage engine
func (r *Remote) Close() error {
_, err := r.Call("close")
_, err := r.Call("store.close")
return err
}
+31 -25
View File
@@ -17,11 +17,14 @@ import (
)
func TestClient_Create(t *testing.T) {
ts := testServer(t, `{"method":"create","params":{"id":"123","pid":"","text":"msg","user":{"name":"","id":"","picture":"","admin":false},"locator":{"site":"site","url":"http://example.com/url"},"score":0,"vote":0,"time":"0001-01-01T00:00:00Z"},"id":1}`,
ts := testServer(t, `{"method":"store.create","params":{"id":"123","pid":"","text":"msg","user":{"name":"","id":"","picture":"","admin":false},"locator":{"site":"site","url":"http://example.com/url"},"score":0,"vote":0,"time":"0001-01-01T00:00:00Z"},"id":1}`,
`{"result":"12345","id":1}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
var eng Interface = &c
_ = eng
res, err := c.Create(store.Comment{ID: "123", Locator: store.Locator{URL: "http://example.com/url", SiteID: "site"},
Text: "msg"})
assert.NoError(t, err)
@@ -30,41 +33,44 @@ func TestClient_Create(t *testing.T) {
}
func TestClient_Get(t *testing.T) {
ts := testServer(t, `{"method":"get","params":[{"url":"http://example.com/url"},"site"],"id":1}`,
`{"result":{"id":"123","pid":"","text":"msg","delete":true}}`)
ts := testServer(t, `{"method":"store.get","params":{"locator":{"url":"http://example.com/url"},"comment_id":"site"},"id":1}`, `{"result":{"id":"123","pid":"","text":"msg","delete":true}}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
res, err := c.Get(store.Locator{URL: "http://example.com/url"}, "site")
req := GetRequest{Locator: store.Locator{URL: "http://example.com/url"}, CommentID: "site"}
res, err := c.Get(req)
assert.NoError(t, err)
assert.Equal(t, store.Comment{ID: "123", Text: "msg", Deleted: true}, res)
t.Logf("%v %T", res, res)
}
func TestClient_GetWithErrorResult(t *testing.T) {
ts := testServer(t, `{"method":"get","params":[{"url":"http://example.com/url"},"site"],"id":1}`, `{"error":"failed"}`)
ts := testServer(t, `{"method":"store.get","params":{"locator":{"url":"http://example.com/url"},"comment_id":"site"},"id":1}`, `{"error":"failed"}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
_, err := c.Get(store.Locator{URL: "http://example.com/url"}, "site")
req := GetRequest{Locator: store.Locator{URL: "http://example.com/url"}, CommentID: "site"}
_, err := c.Get(req)
assert.EqualError(t, err, "failed")
}
func TestClient_GetWithErrorDecode(t *testing.T) {
ts := testServer(t, `{"method":"get","params":[{"url":"http://example.com/url"},"site"],"id":1}`, ``)
ts := testServer(t, `{"method":"store.get","params":{"locator":{"url":"http://example.com/url"},"comment_id":"site"},"id":1}`, ``)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
_, err := c.Get(store.Locator{URL: "http://example.com/url"}, "site")
assert.EqualError(t, err, "failed to decode response for get: EOF")
req := GetRequest{Locator: store.Locator{URL: "http://example.com/url"}, CommentID: "site"}
_, err := c.Get(req)
assert.EqualError(t, err, "failed to decode response for store.get: EOF")
}
func TestClient_GetWithErrorRemote(t *testing.T) {
c := Remote{Client: remote.Client{API: "http://127.0.0.2", Client: http.Client{Timeout: 10 * time.Millisecond}}}
_, err := c.Get(store.Locator{URL: "http://example.com/url"}, "site")
req := GetRequest{Locator: store.Locator{URL: "http://example.com/url"}, CommentID: "site"}
_, err := c.Get(req)
assert.NotNil(t, err)
assert.True(t, strings.Contains(err.Error(), "remote call failed for get:"), err.Error())
assert.True(t, strings.Contains(err.Error(), "remote call failed for store.get:"), err.Error())
}
func TestClient_FailedStatus(t *testing.T) {
@@ -77,23 +83,24 @@ func TestClient_FailedStatus(t *testing.T) {
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
_, err := c.Get(store.Locator{URL: "http://example.com/url"}, "site")
assert.EqualError(t, err, "bad status 400 for get")
req := GetRequest{Locator: store.Locator{URL: "http://example.com/url"}, CommentID: "site"}
_, err := c.Get(req)
assert.EqualError(t, err, "bad status 400 for store.get")
}
func TestClient_Update(t *testing.T) {
ts := testServer(t, `{"method":"update","params":[{"url":"http://example.com/url"},{"id":"123","pid":"","text":"msg","user":{"name":"","id":"","picture":"","admin":false},"locator":{"site":"site123","url":"http://example.com/url"},"score":0,"vote":0,"time":"0001-01-01T00:00:00Z"}],"id":1}`, `{}`)
ts := testServer(t, `{"method":"store.update","params":{"id":"123","pid":"","text":"msg","user":{"name":"","id":"","picture":"","admin":false},"locator":{"site":"site123","url":"http://example.com/url"},"score":0,"vote":0,"time":"0001-01-01T00:00:00Z"},"id":1}`, `{}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
err := c.Update(store.Locator{URL: "http://example.com/url"}, store.Comment{ID: "123",
Locator: store.Locator{URL: "http://example.com/url", SiteID: "site123"}, Text: "msg"})
err := c.Update(store.Comment{ID: "123", Locator: store.Locator{URL: "http://example.com/url", SiteID: "site123"},
Text: "msg"})
assert.NoError(t, err)
}
func TestClient_Find(t *testing.T) {
ts := testServer(t, `{"method":"find","params":{"locator":{"url":"http://example.com/url"},"sort":"-time","since":"0001-01-01T00:00:00Z","limit":10},"id":1}`, `{"result":[{"text":"1"},{"text":"2"}]}`)
ts := testServer(t, `{"method":"store.find","params":{"locator":{"url":"http://example.com/url"},"sort":"-time","since":"0001-01-01T00:00:00Z","limit":10},"id":1}`, `{"result":[{"text":"1"},{"text":"2"}]}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
@@ -103,7 +110,7 @@ func TestClient_Find(t *testing.T) {
}
func TestClient_Info(t *testing.T) {
ts := testServer(t, `{"method":"info","params":{"locator":{"url":"http://example.com/url"},"limit":10,"skip":5,"ro_age":10},"id":1}`, `{"result":[{"url":"u1","count":22},{"url":"u2","count":33}]}`)
ts := testServer(t, `{"method":"store.info","params":{"locator":{"url":"http://example.com/url"},"limit":10,"skip":5,"ro_age":10},"id":1}`, `{"result":[{"url":"u1","count":22},{"url":"u2","count":33}]}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
@@ -114,8 +121,7 @@ func TestClient_Info(t *testing.T) {
}
func TestClient_Flag(t *testing.T) {
ts := testServer(t, `{"method":"flag","params":{"flag":"verified","locator":{"url":"http://example.com/url"}},"id":1}`,
`{"result":false}`)
ts := testServer(t, `{"method":"store.flag","params":{"flag":"verified","locator":{"url":"http://example.com/url"}},"id":1}`, `{"result":false}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
@@ -125,8 +131,7 @@ func TestClient_Flag(t *testing.T) {
}
func TestClient_ListFlag(t *testing.T) {
ts := testServer(t, `{"method":"list_flags","params":{"flag":"blocked","locator":{"site":"site_id","url":""}},"id":1}`,
`{"result":[{"ID":"id1"},{"ID":"id2"}]}`)
ts := testServer(t, `{"method":"store.list_flags","params":{"flag":"blocked","locator":{"site":"site_id","url":""}},"id":1}`, `{"result":[{"ID":"id1"},{"ID":"id2"}]}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
res, err := c.ListFlags(FlagRequest{Locator: store.Locator{SiteID: "site_id"}, Flag: Blocked})
@@ -135,7 +140,7 @@ func TestClient_ListFlag(t *testing.T) {
}
func TestClient_Count(t *testing.T) {
ts := testServer(t, `{"method":"count","params":{"locator":{"url":"http://example.com/url"},"since":"0001-01-01T00:00:00Z"},"id":1}`, `{"result":11}`)
ts := testServer(t, `{"method":"store.count","params":{"locator":{"url":"http://example.com/url"},"since":"0001-01-01T00:00:00Z"},"id":1}`, `{"result":11}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
@@ -145,7 +150,8 @@ func TestClient_Count(t *testing.T) {
}
func TestClient_Delete(t *testing.T) {
ts := testServer(t, `{"method":"delete","params":{"locator":{"url":"http://example.com/url"},"del_mode":0},"id":1}`, `{}`)
ts := testServer(t, `{"method":"store.delete","params":{"locator":{"url":"http://example.com/url"},"del_mode":0},"id":1}`,
`{}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
@@ -154,7 +160,7 @@ func TestClient_Delete(t *testing.T) {
}
func TestClient_Close(t *testing.T) {
ts := testServer(t, `{"method":"close","params":null,"id":1}`, `{}`)
ts := testServer(t, `{"method":"store.close","params":null,"id":1}`, `{}`)
defer ts.Close()
c := Remote{Client: remote.Client{API: ts.URL, Client: http.Client{}}}
err := c.Close()
+18 -13
View File
@@ -132,7 +132,7 @@ func (s *DataStore) Find(locator store.Locator, sort string, user store.User) ([
// Get comment by ID
func (s *DataStore) Get(locator store.Locator, commentID string, user store.User) (store.Comment, error) {
c, err := s.Engine.Get(locator, commentID)
c, err := s.Engine.Get(engine.GetRequest{Locator: locator, CommentID: commentID})
if err != nil {
return store.Comment{}, err
}
@@ -141,7 +141,8 @@ func (s *DataStore) Get(locator store.Locator, commentID string, user store.User
// Put updates comment, mutable parts only
func (s *DataStore) Put(locator store.Locator, comment store.Comment) error {
return s.Engine.Update(locator, comment)
comment.Locator = locator
return s.Engine.Update(comment)
}
// submitImages initiated delayed commit of all images from the comment uploaded to remark42
@@ -149,7 +150,8 @@ func (s *DataStore) submitImages(comment store.Comment) {
s.ImageService.Submit(func() []string {
c := comment
cc, err := s.Engine.Get(c.Locator, c.ID) // this can be called after last edit, we have to retrieve fresh comment
// this can be called after last edit, we have to retrieve fresh comment
cc, err := s.Engine.Get(engine.GetRequest{Locator: c.Locator, CommentID: c.ID})
if err != nil {
log.Printf("[WARN] can't get comment's %s text for image extraction, %v", c.ID, err)
return nil
@@ -197,12 +199,13 @@ func (s *DataStore) DeleteAll(siteID string) error {
// SetPin pin/un-pin comment as special
func (s *DataStore) SetPin(locator store.Locator, commentID string, status bool) error {
comment, err := s.Engine.Get(locator, commentID)
comment, err := s.Engine.Get(engine.GetRequest{Locator: locator, CommentID: commentID})
if err != nil {
return err
}
comment.Pin = status
return s.Engine.Update(locator, comment)
comment.Locator = locator
return s.Engine.Update(comment)
}
// Vote for comment by id and locator
@@ -212,7 +215,7 @@ func (s *DataStore) Vote(locator store.Locator, commentID string, userID string,
cLock.Lock() // prevents race on voting
defer cLock.Unlock()
comment, err = s.Engine.Get(locator, commentID)
comment, err = s.Engine.Get(engine.GetRequest{Locator: locator, CommentID: commentID})
if err != nil {
return comment, err
}
@@ -270,8 +273,8 @@ func (s *DataStore) Vote(locator store.Locator, commentID string, userID string,
}
comment.Controversy = s.controversy(s.upsAndDowns(comment))
return comment, s.Engine.Update(locator, comment)
comment.Locator = locator
return comment, s.Engine.Update(comment)
}
// controversy calculates controversial index of votes
@@ -300,7 +303,7 @@ type EditRequest struct {
// EditComment to edit text and update Edit info
func (s *DataStore) EditComment(locator store.Locator, commentID string, req EditRequest) (comment store.Comment, err error) {
comment, err = s.Engine.Get(locator, commentID)
comment, err = s.Engine.Get(engine.GetRequest{Locator: locator, CommentID: commentID})
if err != nil {
return comment, err
}
@@ -330,9 +333,10 @@ func (s *DataStore) EditComment(locator store.Locator, commentID string, req Edi
Timestamp: time.Now(),
Summary: req.Summary,
}
comment.Locator = locator
comment.Sanitize()
err = s.Engine.Update(locator, comment)
err = s.Engine.Update(comment)
return comment, err
}
@@ -410,7 +414,7 @@ func (s *DataStore) SetTitle(locator store.Locator, commentID string) (comment s
return comment, errors.New("no title extractor")
}
comment, err = s.Engine.Get(locator, commentID)
comment, err = s.Engine.Get(engine.GetRequest{Locator: locator, CommentID: commentID})
if err != nil {
return comment, err
}
@@ -421,7 +425,8 @@ func (s *DataStore) SetTitle(locator store.Locator, commentID string) (comment s
return comment, err
}
comment.PostTitle = title
err = s.Engine.Update(locator, comment)
comment.Locator = locator
err = s.Engine.Update(comment)
return comment, err
}
+16 -9
View File
@@ -40,7 +40,7 @@ func TestService_CreateFromEmpty(t *testing.T) {
assert.NoError(t, err)
assert.True(t, id != "", id)
res, err := b.Engine.Get(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, id)
res, err := b.Engine.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, id))
assert.NoError(t, err)
t.Logf("%+v", res)
assert.Equal(t, "text", res.Text)
@@ -66,7 +66,7 @@ func TestService_CreateFromPartial(t *testing.T) {
assert.NoError(t, err)
assert.True(t, id != "", id)
res, err := b.Engine.Get(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, id)
res, err := b.Engine.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, id))
assert.NoError(t, err)
t.Logf("%+v", res)
assert.Equal(t, "text", res.Text)
@@ -94,7 +94,7 @@ func TestService_CreateFromPartialWithTitle(t *testing.T) {
assert.NoError(t, err)
assert.True(t, id != "", id)
res, err := b.Engine.Get(store.Locator{URL: "https://radio-t.com/p/2018/12/29/podcast-630/", SiteID: "radio-t"}, id)
res, err := b.Engine.Get(getReq(store.Locator{URL: "https://radio-t.com/p/2018/12/29/podcast-630/", SiteID: "radio-t"}, id))
assert.NoError(t, err)
t.Logf("%+v", res)
assert.Equal(t, "Радио-Т 630 — Радио-Т Подкаст", res.PostTitle)
@@ -102,7 +102,7 @@ func TestService_CreateFromPartialWithTitle(t *testing.T) {
comment.PostTitle = "post blah"
id, err = b.Create(comment)
assert.NoError(t, err)
res, err = b.Engine.Get(store.Locator{URL: "https://radio-t.com/p/2018/12/29/podcast-630/", SiteID: "radio-t"}, id)
res, err = b.Engine.Get(getReq(store.Locator{URL: "https://radio-t.com/p/2018/12/29/podcast-630/", SiteID: "radio-t"}, id))
assert.NoError(t, err)
t.Logf("%+v", res)
assert.Equal(t, "post blah", res.PostTitle, "keep comment title")
@@ -145,7 +145,7 @@ func TestService_SetTitle(t *testing.T) {
assert.NoError(t, err)
assert.True(t, id != "", id)
res, err := b.Engine.Get(store.Locator{URL: tss.URL + "/post1", SiteID: "radio-t"}, id)
res, err := b.Engine.Get(getReq(store.Locator{URL: tss.URL + "/post1", SiteID: "radio-t"}, id))
assert.NoError(t, err)
t.Logf("%+v", res)
assert.Equal(t, "", res.PostTitle)
@@ -438,13 +438,13 @@ func TestService_Pin(t *testing.T) {
err = b.SetPin(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID, true)
assert.NoError(t, err)
c, err := b.Engine.Get(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID)
c, err := b.Engine.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID))
assert.NoError(t, err)
assert.Equal(t, true, c.Pin)
err = b.SetPin(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID, false)
assert.NoError(t, err)
c, err = b.Engine.Get(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID)
c, err = b.Engine.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID))
assert.NoError(t, err)
assert.Equal(t, false, c.Pin)
}
@@ -466,7 +466,7 @@ func TestService_EditComment(t *testing.T) {
assert.Equal(t, "xxx", comment.Text)
assert.Equal(t, "yyy", comment.Orig)
c, err := b.Engine.Get(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID)
c, err := b.Engine.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID))
assert.NoError(t, err)
assert.Equal(t, "my edit", c.Edit.Summary)
assert.Equal(t, "xxx", c.Text)
@@ -489,7 +489,7 @@ func TestService_DeleteComment(t *testing.T) {
_, err = b.EditComment(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID, EditRequest{Delete: true})
assert.NoError(t, err)
c, err := b.Engine.Get(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID)
c, err := b.Engine.Get(getReq(store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID))
assert.NoError(t, err)
assert.True(t, c.Deleted)
t.Logf("%+v", c)
@@ -1079,3 +1079,10 @@ func prepStoreEngine(t *testing.T) engine.Interface {
func teardown(_ *testing.T) {
_ = os.Remove(testDb)
}
func getReq(locator store.Locator, commentID string) engine.GetRequest {
return engine.GetRequest{
Locator: locator,
CommentID: commentID,
}
}