remote client adjusted to new engine flavour
This commit is contained in:
@@ -22,7 +22,7 @@ type Interface interface {
|
||||
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
|
||||
Delete(req DeleteRequest) error // delete post(s) by id or by userID
|
||||
Flag(req FlagRequest) (bool, error) // set and get flags
|
||||
ListFlags(siteID string, flag Flag) ([]interface{}, error) // get list of flagged keys, like blocked & verified user
|
||||
Close() error // close storage engine
|
||||
@@ -30,25 +30,28 @@ type Interface interface {
|
||||
|
||||
// FindRequest is the input for all find operations
|
||||
type FindRequest struct {
|
||||
Locator store.Locator // lack of URL means site operation
|
||||
UserID string // presence of UserID treated as user-related find
|
||||
Sort string // sort order with +/-field syntax
|
||||
Since time.Time // time limit for found results
|
||||
Limit, Skip int
|
||||
Locator store.Locator `json:"locator"` // lack of URL means site operation
|
||||
UserID string `json:"user_id,omitempty"` // presence of UserID treated as user-related find
|
||||
Sort string `json:"sort,omitempty"` // sort order with +/-field syntax
|
||||
Since time.Time `json:"since,omitempty"` // time limit for found results
|
||||
Limit int `json:"limit,omitempty"`
|
||||
Skip int `json:"skip,omitempty"`
|
||||
}
|
||||
|
||||
// InfoRequest is the input of Info operation used to get meta data about posts
|
||||
type InfoRequest struct {
|
||||
Locator store.Locator
|
||||
Limit, Skip int
|
||||
ReadOnlyAge int
|
||||
Locator store.Locator `json:"locator"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
Skip int `json:"skip,omitempty"`
|
||||
ReadOnlyAge int `json:"ro_age,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteRequest is the input for all delete operations (comments, sites, users)
|
||||
type DeleteRequest struct {
|
||||
Locator store.Locator // lack of URL means site operation
|
||||
CommentID string
|
||||
UserID string
|
||||
DeleteMode store.DeleteMode
|
||||
Locator store.Locator `json:"locator"` // lack of URL means site operation
|
||||
CommentID string `json:"comment_id,omitempty"`
|
||||
UserID string `json:"user_id,omitempty"`
|
||||
DeleteMode store.DeleteMode `json:"del_mode"`
|
||||
}
|
||||
|
||||
// Flag defines type of binary attribute
|
||||
@@ -73,11 +76,11 @@ const (
|
||||
|
||||
// FlagRequest is the input for both get/set for flags, like blocked, verified and so on
|
||||
type FlagRequest struct {
|
||||
Flag Flag // flag type
|
||||
Locator store.Locator // post locator
|
||||
UserID string // for flags setting user status
|
||||
Update FlagStatus // if FlagNonSet it will be get op, if set will set the value
|
||||
TTL time.Duration // ttl for time-sensitive flags only, like blocked for some period
|
||||
Flag Flag `json:"flag"` // flag type
|
||||
Locator store.Locator `json:"locator"` // post locator
|
||||
UserID string `json:"user_id,omitempty"` // for flags setting user status
|
||||
Update FlagStatus `json:"update,omitempty"` // if FlagNonSet it will be get op, if set will set the value
|
||||
TTL time.Duration `json:"ttl,omitempty"` // ttl for time-sensitive flags only, like blocked for some period
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
)
|
||||
|
||||
// Client implements remote engine and delegates all calls to remote http server
|
||||
@@ -54,45 +54,55 @@ func (r *Client) Get(locator store.Locator, commentID string) (comment store.Com
|
||||
return comment, err
|
||||
}
|
||||
|
||||
// Put updates comment, mutable parts only
|
||||
func (r *Client) Put(locator store.Locator, comment store.Comment) error {
|
||||
_, err := r.call("put", locator, comment)
|
||||
// Update comment, mutable parts only
|
||||
func (r *Client) Update(locator store.Locator, comment store.Comment) error {
|
||||
_, err := r.call("update", locator, comment)
|
||||
return err
|
||||
}
|
||||
|
||||
// Find comments for locator
|
||||
func (r *Client) Find(locator store.Locator, sort string) (comments []store.Comment, err error) {
|
||||
resp, err := r.call("find", locator, sort)
|
||||
func (r *Client) Find(req engine.FindRequest) (comments []store.Comment, err error) {
|
||||
resp, err := r.call("find", req)
|
||||
if err != nil {
|
||||
return []store.Comment{}, err
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal(*resp.Result, &comments)
|
||||
return comments, err
|
||||
}
|
||||
|
||||
// Last comments for given site, sorted by time
|
||||
func (r *Client) Last(siteID string, limit int, since time.Time) (comments []store.Comment, err error) {
|
||||
resp, err := r.call("last", siteID, limit, since)
|
||||
// Info returns post(s) meta info
|
||||
func (r *Client) Info(req engine.InfoRequest) (info []store.PostInfo, err error) {
|
||||
resp, err := r.call("info", req)
|
||||
if err != nil {
|
||||
return []store.Comment{}, err
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal(*resp.Result, &comments)
|
||||
return comments, err
|
||||
err = json.Unmarshal(*resp.Result, &info)
|
||||
return info, err
|
||||
}
|
||||
|
||||
// User get comments by user, sorted by time
|
||||
func (r *Client) User(siteID, userID string, limit, skip int) (comments []store.Comment, err error) {
|
||||
resp, err := r.call("user", siteID, userID, limit, skip)
|
||||
// Flag sets and gets flags
|
||||
func (r *Client) Flag(req engine.FlagRequest) (status bool, err error) {
|
||||
resp, err := r.call("flag", req)
|
||||
if err != nil {
|
||||
return []store.Comment{}, err
|
||||
return false, err
|
||||
}
|
||||
err = json.Unmarshal(*resp.Result, &comments)
|
||||
return comments, err
|
||||
err = json.Unmarshal(*resp.Result, &status)
|
||||
return status, err
|
||||
}
|
||||
|
||||
// UserCount gets comments count by user
|
||||
func (r *Client) UserCount(siteID, userID string) (count int, err error) {
|
||||
resp, err := r.call("user_count", siteID, userID)
|
||||
// ListFlags get list of flagged keys, like blocked & verified user
|
||||
func (r *Client) ListFlags(siteID string, flag engine.Flag) (list []interface{}, err error) {
|
||||
resp, err := r.call("list_flags", siteID, flag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal(*resp.Result, &list)
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Count gets comments count by user or site
|
||||
func (r *Client) Count(req engine.FindRequest) (count int, err error) {
|
||||
resp, err := r.call("count", req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -100,6 +110,18 @@ func (r *Client) UserCount(siteID, userID string) (count int, err error)
|
||||
return count, err
|
||||
}
|
||||
|
||||
// Delete post(s) by id or by userID
|
||||
func (r *Client) Delete(req engine.DeleteRequest) error {
|
||||
_, err := r.call("delete", req)
|
||||
return err
|
||||
}
|
||||
|
||||
// Close storage engine
|
||||
func (r *Client) Close() error {
|
||||
_, err := r.call("close")
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Client) call(method string, args ...interface{}) (*Response, error) {
|
||||
|
||||
b, err := json.Marshal(Request{Method: method, Params: args})
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
)
|
||||
|
||||
func TestClient_Create(t *testing.T) {
|
||||
@@ -79,47 +80,84 @@ func TestClient_FailedStatus(t *testing.T) {
|
||||
assert.EqualError(t, err, "bad status 400 for get")
|
||||
}
|
||||
|
||||
func TestClient_Put(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"put","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"}]}`, `{}`)
|
||||
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"}]}`, `{}`)
|
||||
defer ts.Close()
|
||||
c := Client{API: ts.URL, Client: http.Client{}}
|
||||
|
||||
err := c.Put(store.Locator{URL: "http://example.com/url"}, store.Comment{ID: "123",
|
||||
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"})
|
||||
assert.NoError(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestClient_Find(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"find","params":[{"url":"http://example.com/url"},""]}`,
|
||||
`{"result":[{"text":"1"},{"text":"2"}]}`)
|
||||
ts := testServer(t, `{"method":"find","params":[{"locator":{"url":"http://example.com/url"},"sort":"-time","since":"0001-01-01T00:00:00Z","limit":10}]}`, `{"result":[{"text":"1"},{"text":"2"}]}`)
|
||||
defer ts.Close()
|
||||
c := Client{API: ts.URL, Client: http.Client{}}
|
||||
|
||||
res, err := c.Find(store.Locator{URL: "http://example.com/url"}, "")
|
||||
res, err := c.Find(engine.FindRequest{Locator: store.Locator{URL: "http://example.com/url"}, Sort: "-time", Limit: 10})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []store.Comment{{Text: "1"}, {Text: "2"}}, res)
|
||||
}
|
||||
|
||||
func TestClient_Last(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"last","params":["site1",100,"2019-06-06T19:34:10Z"]}`,
|
||||
`{"result":[{"text":"1"},{"text":"2"}]}`)
|
||||
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}]}`, `{"result":[{"url":"u1","count":22},{"url":"u2","count":33}]}`)
|
||||
defer ts.Close()
|
||||
c := Client{API: ts.URL, Client: http.Client{}}
|
||||
|
||||
res, err := c.Last("site1", 100, time.Date(2019, 6, 6, 19, 34, 10, 0, time.UTC))
|
||||
res, err := c.Info(engine.InfoRequest{Locator: store.Locator{URL: "http://example.com/url"},
|
||||
Limit: 10, Skip: 5, ReadOnlyAge: 10})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []store.Comment{{Text: "1"}, {Text: "2"}}, res)
|
||||
assert.Equal(t, []store.PostInfo{{URL: "u1", Count: 22}, {URL: "u2", Count: 33}}, res)
|
||||
}
|
||||
|
||||
func TestClient_User(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"user","params":["site1","u1",100,4]}`, `{"result":[{"text":"1"},{"text":"2"}]}`)
|
||||
func TestClient_Flag(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"flag","params":[{"flag":"verified","locator":{"url":"http://example.com/url"}}]}`,
|
||||
`{"result":false}`)
|
||||
defer ts.Close()
|
||||
c := Client{API: ts.URL, Client: http.Client{}}
|
||||
|
||||
res, err := c.User("site1", "u1", 100, 4)
|
||||
res, err := c.Flag(engine.FlagRequest{Locator: store.Locator{URL: "http://example.com/url"}, Flag: engine.Verified})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, false, res)
|
||||
}
|
||||
|
||||
func TestClient_ListFlag(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"list_flags","params":["site_id","blocked"]}`, `{"result":[{"ID":"id1"},{"ID":"id2"}]}`)
|
||||
defer ts.Close()
|
||||
c := Client{API: ts.URL, Client: http.Client{}}
|
||||
res, err := c.ListFlags("site_id", engine.Blocked)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []interface{}{map[string]interface{}{"ID": "id1"}, map[string]interface{}{"ID": "id2"}}, res)
|
||||
}
|
||||
|
||||
func TestClient_Count(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"count","params":[{"locator":{"url":"http://example.com/url"},"since":"0001-01-01T00:00:00Z"}]}`,
|
||||
`{"result":11}`)
|
||||
defer ts.Close()
|
||||
c := Client{API: ts.URL, Client: http.Client{}}
|
||||
|
||||
res, err := c.Count(engine.FindRequest{Locator: store.Locator{URL: "http://example.com/url"}})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 11, res)
|
||||
}
|
||||
|
||||
func TestClient_Delete(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"delete","params":[{"locator":{"url":"http://example.com/url"},"del_mode":0}]}`, `{}`)
|
||||
defer ts.Close()
|
||||
c := Client{API: ts.URL, Client: http.Client{}}
|
||||
|
||||
err := c.Delete(engine.DeleteRequest{Locator: store.Locator{URL: "http://example.com/url"}})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestClient_Close(t *testing.T) {
|
||||
ts := testServer(t, `{"method":"close","params":null}`, `{}`)
|
||||
defer ts.Close()
|
||||
c := Client{API: ts.URL, Client: http.Client{}}
|
||||
err := c.Close()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []store.Comment{{Text: "1"}, {Text: "2"}}, res)
|
||||
}
|
||||
|
||||
func testServer(t *testing.T, req, resp string) *httptest.Server {
|
||||
|
||||
Reference in New Issue
Block a user