find user comments to support pagination
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
/web/public/
|
||||
/.vscode/
|
||||
/.idea/
|
||||
#/.git/
|
||||
|
||||
# source files
|
||||
docker-compose.yml
|
||||
|
||||
+4
-1
@@ -31,7 +31,10 @@ RUN if [ -z "$COVERALLS_TOKEN" ] ; then \
|
||||
echo coverall not enabled ; \
|
||||
else goveralls -coverprofile=.cover/cover.out -service=travis-ci -repotoken $COVERALLS_TOKEN; fi
|
||||
|
||||
RUN go build -o remark -ldflags "-X main.revision=$(git rev-parse --abbrev-ref HEAD)-$(git describe --abbrev=7 --always --tags)-$(date +%Y%m%d-%H:%M:%S) -s -w" ./app
|
||||
RUN \
|
||||
version=$(git rev-parse --abbrev-ref HEAD)-$(git describe --abbrev=7 --always --tags)-$(date +%Y%m%d-%H:%M:%S) && \
|
||||
echo "version $version" && \
|
||||
go build -o remark -ldflags "-X main.revision=${version} -s -w" ./app
|
||||
|
||||
|
||||
FROM node:9.4-alpine as build-frontend
|
||||
|
||||
@@ -444,7 +444,7 @@ func (s *Rest) findUserCommentsCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("[DEBUG] get comments for userID %s, %s", userID, siteID)
|
||||
|
||||
data, err := s.Cache.Get(cache.Key(cache.URLKey(r), userID, siteID), func() ([]byte, error) {
|
||||
comments, count, e := s.DataService.User(siteID, userID, limit)
|
||||
comments, count, e := s.DataService.User(siteID, userID, limit, 0)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ func (b *BoltDB) Info(locator store.Locator, readOnlyAge int) (store.PostInfo, e
|
||||
|
||||
// User extracts all comments for given site and given userID
|
||||
// "users" bucket has sub-bucket for each userID, and keeps it as ts:ref
|
||||
func (b *BoltDB) User(siteID string, userID string, limit int) (comments []store.Comment, totalComments int, err error) {
|
||||
func (b *BoltDB) User(siteID, userID string, limit, skip int) (comments []store.Comment, totalComments int, err error) {
|
||||
|
||||
comments = []store.Comment{}
|
||||
commentRefs := []string{}
|
||||
@@ -318,8 +318,13 @@ func (b *BoltDB) User(siteID string, userID string, limit int) (comments []store
|
||||
|
||||
c := userIDBkt.Cursor()
|
||||
totalComments = 0
|
||||
skipComments := 0
|
||||
for k, v := c.Last(); k != nil; k, v = c.Prev() {
|
||||
totalComments++
|
||||
if skip > 0 && skipComments < skip {
|
||||
skipComments++
|
||||
continue
|
||||
}
|
||||
if len(commentRefs) < limit {
|
||||
commentRefs = append(commentRefs, string(v))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -224,25 +225,82 @@ func TestBoltDB_GetForUser(t *testing.T) {
|
||||
defer os.Remove(testDb)
|
||||
b := prep(t)
|
||||
|
||||
res, count, err := b.User("radio-t", "user1", 5)
|
||||
res, count, err := b.User("radio-t", "user1", 5, 0)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(res))
|
||||
assert.Equal(t, 2, count)
|
||||
assert.Equal(t, "some text2", res[0].Text, "sorted by -time")
|
||||
|
||||
res, count, err = b.User("radio-t", "user1", 1)
|
||||
res, count, err = b.User("radio-t", "user1", 1, 0)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(res), "allow 1 comment")
|
||||
assert.Equal(t, 2, count)
|
||||
assert.Equal(t, "some text2", res[0].Text, "sorted by -time")
|
||||
|
||||
_, _, err = b.User("bad", "user1", 1)
|
||||
res, count, err = b.User("radio-t", "user1", 1, 1)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(res), "allow 1 comment")
|
||||
assert.Equal(t, 2, count)
|
||||
assert.Equal(t, `some text, <a href="http://radio-t.com">link</a>`, res[0].Text, "second comment")
|
||||
|
||||
_, _, err = b.User("bad", "user1", 1, 0)
|
||||
assert.EqualError(t, err, `site "bad" not found`)
|
||||
|
||||
_, _, err = b.User("radio-t", "userZ", 1)
|
||||
_, _, err = b.User("radio-t", "userZ", 1, 0)
|
||||
assert.EqualError(t, err, `no comments for user userZ in store`)
|
||||
}
|
||||
|
||||
func TestBoltDB_GetForUserPagination(t *testing.T) {
|
||||
os.Remove(testDb)
|
||||
b, err := NewBoltDB(bolt.Options{}, BoltSite{FileName: testDb, SiteID: "radio-t"})
|
||||
require.Nil(t, err)
|
||||
defer os.Remove(testDb)
|
||||
|
||||
c := store.Comment{
|
||||
Locator: store.Locator{URL: "https://radio-t.com", SiteID: "radio-t"},
|
||||
User: store.User{ID: "user1", Name: "user name"},
|
||||
}
|
||||
|
||||
// write 50 comments
|
||||
for i := 0; i < 50; i++ {
|
||||
c.ID = fmt.Sprintf("id-%d", i)
|
||||
c.Text = fmt.Sprintf("text #%d", i)
|
||||
c.Timestamp = time.Date(2017, 12, 20, 15, 18, i, 0, time.Local)
|
||||
_, err = b.Create(c)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
// seek 0, 5 comments
|
||||
res, count, err := b.User("radio-t", "user1", 5, 0)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 50, count)
|
||||
assert.Equal(t, 5, len(res))
|
||||
assert.Equal(t, "id-49", res[0].ID)
|
||||
assert.Equal(t, "id-45", res[4].ID)
|
||||
|
||||
// seek 10, 3 comments
|
||||
res, count, err = b.User("radio-t", "user1", 3, 10)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 50, count)
|
||||
assert.Equal(t, 3, len(res))
|
||||
assert.Equal(t, "id-39", res[0].ID)
|
||||
assert.Equal(t, "id-37", res[2].ID)
|
||||
|
||||
// seek 45, ask 10 comments
|
||||
res, count, err = b.User("radio-t", "user1", 10, 45)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 50, count)
|
||||
assert.Equal(t, 5, len(res))
|
||||
assert.Equal(t, "id-4", res[0].ID)
|
||||
assert.Equal(t, "id-0", res[4].ID)
|
||||
|
||||
// seek 55, ask 10 comments
|
||||
res, count, err = b.User("radio-t", "user1", 10, 55)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 50, count)
|
||||
assert.Equal(t, 0, len(res))
|
||||
}
|
||||
|
||||
func TestBoltDB_Ref(t *testing.T) {
|
||||
b := BoltDB{}
|
||||
comment := store.Comment{
|
||||
|
||||
@@ -206,10 +206,10 @@ func (b *BoltDB) Blocked(siteID string) (users []store.BlockedUser, err error) {
|
||||
|
||||
// get user name from comment user section
|
||||
userName := ""
|
||||
if userComments, _, e := b.User(siteID, string(k), 1); e == nil && len(userComments) > 0 {
|
||||
userComments, _, e := b.User(siteID, string(k), 1, 0)
|
||||
if e == nil && len(userComments) > 0 {
|
||||
userName = userComments[0].User.Name
|
||||
}
|
||||
|
||||
users = append(users, store.BlockedUser{ID: string(k), Name: userName, Timestamp: ts})
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -109,7 +109,7 @@ func TestBoltAdmin_DeleteUser(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, c, "0 count")
|
||||
|
||||
_, _, err = b.User("radio-t", "user1", 5)
|
||||
_, _, err = b.User("radio-t", "user1", 5, 0)
|
||||
assert.EqualError(t, err, "no comments for user user1 in store")
|
||||
|
||||
comments, err := b.Last("radio-t", 10)
|
||||
|
||||
@@ -17,17 +17,25 @@ type Interface interface {
|
||||
Admin
|
||||
}
|
||||
|
||||
// UserRequest is the request send to get comments by user
|
||||
type UserRequest struct {
|
||||
SiteID string
|
||||
UserID string
|
||||
Limit int
|
||||
Skip int
|
||||
}
|
||||
|
||||
// Accessor defines all usual access ops avail for regular user
|
||||
type Accessor interface {
|
||||
Create(comment store.Comment) (commentID string, err error) // create new comment, avoid dups by id
|
||||
Get(locator store.Locator, commentID string) (store.Comment, error) // get comment by id
|
||||
Put(locator store.Locator, comment store.Comment) error // update comment, mutable parts only
|
||||
Find(locator store.Locator, sort string) ([]store.Comment, error) // find comments for locator
|
||||
Last(siteID string, limit int) ([]store.Comment, error) // last comments for given site, sorted by time
|
||||
User(siteID string, userID string, limit int) ([]store.Comment, int, error) // comments by user, sorted by time
|
||||
Count(locator store.Locator) (int, error) // number of comments for the post
|
||||
List(siteID string, limit int, skip int) ([]store.PostInfo, error) // list of commented posts
|
||||
Info(locator store.Locator, readonlyAge int) (store.PostInfo, error) // get post info
|
||||
Create(comment store.Comment) (commentID string, err error) // create new comment, avoid dups by id
|
||||
Get(locator store.Locator, commentID string) (store.Comment, error) // get comment by id
|
||||
Put(locator store.Locator, comment store.Comment) error // update comment, mutable parts only
|
||||
Find(locator store.Locator, sort string) ([]store.Comment, error) // find comments for locator
|
||||
Last(siteID string, limit int) ([]store.Comment, error) // last comments for given site, sorted by time
|
||||
User(siteID, userID string, limit, skip int) ([]store.Comment, int, error) // comments by user, sorted by time
|
||||
Count(locator store.Locator) (int, error) // number of comments for the post
|
||||
List(siteID string, limit int, skip int) ([]store.PostInfo, error) // list of commented posts
|
||||
Info(locator store.Locator, readonlyAge int) (store.PostInfo, error) // get post info
|
||||
}
|
||||
|
||||
// Admin defines all store ops avail for admin only
|
||||
|
||||
Reference in New Issue
Block a user