397 lines
11 KiB
Go
397 lines
11 KiB
Go
package rest
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/umputun/remark/app/store"
|
|
)
|
|
|
|
func TestMakeTree(t *testing.T) {
|
|
|
|
loc := store.Locator{URL: "url", SiteID: "site"}
|
|
ts := func(min int, sec int) time.Time { return time.Date(2017, 12, 25, 19, min, sec, 0, time.UTC) }
|
|
|
|
// unsorted by purpose
|
|
comments := []store.Comment{
|
|
{Locator: loc, ID: "14", ParentID: "1", Timestamp: ts(46, 14)},
|
|
{Locator: loc, ID: "1", Timestamp: ts(46, 1)},
|
|
{Locator: loc, ID: "2", Timestamp: ts(47, 2)},
|
|
{Locator: loc, ID: "11", ParentID: "1", Timestamp: ts(46, 11)},
|
|
{Locator: loc, ID: "13", ParentID: "1", Timestamp: ts(46, 13)},
|
|
{Locator: loc, ID: "12", ParentID: "1", Timestamp: ts(46, 12)},
|
|
{Locator: loc, ID: "131", ParentID: "13", Timestamp: ts(46, 31)},
|
|
{Locator: loc, ID: "132", ParentID: "13", Timestamp: ts(46, 32)},
|
|
{Locator: loc, ID: "21", ParentID: "2", Timestamp: ts(47, 21)},
|
|
{Locator: loc, ID: "22", ParentID: "2", Timestamp: ts(47, 22)},
|
|
{Locator: loc, ID: "4", Timestamp: ts(47, 22)},
|
|
{Locator: loc, ID: "3", Timestamp: ts(47, 22)},
|
|
{Locator: loc, ID: "5", Deleted: true},
|
|
{Locator: loc, ID: "6", Deleted: true},
|
|
{Locator: loc, ID: "61", ParentID: "6", Deleted: true},
|
|
{Locator: loc, ID: "62", ParentID: "6", Deleted: true},
|
|
{Locator: loc, ID: "611", ParentID: "61", Deleted: true},
|
|
}
|
|
|
|
res := MakeTree(comments, "time", 0)
|
|
|
|
buf := &bytes.Buffer{}
|
|
enc := json.NewEncoder(buf)
|
|
enc.SetIndent("", " ")
|
|
err := enc.Encode(res)
|
|
assert.Nil(t, err)
|
|
expected, actual := cleanFormatting(expJSON, buf.String())
|
|
assert.Equal(t, expected, actual)
|
|
assert.Equal(t, store.PostInfo{URL: "url", Count: 12, FirstTS: ts(46, 1), LastTS: ts(47, 22)}, res.Info)
|
|
|
|
res = MakeTree([]store.Comment{}, "time", 0)
|
|
assert.Equal(t, &Tree{}, res)
|
|
|
|
res = MakeTree(comments, "time", 10)
|
|
assert.Equal(t, store.PostInfo{URL: "url", Count: 12, FirstTS: ts(46, 1), LastTS: ts(47, 22), ReadOnly: true}, res.Info)
|
|
}
|
|
|
|
func TestTreeSortNodes(t *testing.T) {
|
|
// unsorted by purpose
|
|
comments := []store.Comment{
|
|
{ID: "14", ParentID: "1", Timestamp: time.Date(2017, 12, 25, 19, 46, 14, 0, time.UTC)},
|
|
{ID: "132", ParentID: "13", Timestamp: time.Date(2017, 12, 25, 19, 46, 32, 0, time.UTC)},
|
|
{ID: "1", Timestamp: time.Date(2017, 12, 25, 19, 46, 1, 0, time.UTC), Score: 2},
|
|
{ID: "2", Timestamp: time.Date(2017, 12, 25, 19, 47, 2, 0, time.UTC), Score: 3},
|
|
{ID: "11", ParentID: "1", Timestamp: time.Date(2017, 12, 25, 19, 46, 11, 0, time.UTC)},
|
|
{ID: "13", ParentID: "1", Timestamp: time.Date(2017, 12, 25, 19, 46, 13, 0, time.UTC)},
|
|
{ID: "12", ParentID: "1", Timestamp: time.Date(2017, 12, 25, 19, 46, 14, 0, time.UTC)},
|
|
{ID: "131", ParentID: "13", Timestamp: time.Date(2017, 12, 25, 19, 50, 31, 0, time.UTC)},
|
|
{ID: "21", ParentID: "2", Timestamp: time.Date(2017, 12, 25, 19, 47, 21, 0, time.UTC)},
|
|
{ID: "22", ParentID: "2", Timestamp: time.Date(2017, 12, 25, 19, 47, 22, 0, time.UTC)},
|
|
{ID: "4", Timestamp: time.Date(2017, 12, 25, 19, 47, 22, 0, time.UTC), Score: -2},
|
|
{ID: "3", Timestamp: time.Date(2017, 12, 25, 19, 47, 22, 100, time.UTC)},
|
|
{ID: "6", Timestamp: time.Date(2017, 12, 25, 19, 47, 22, 200, time.UTC)},
|
|
{ID: "5", Deleted: true, Timestamp: time.Date(2017, 12, 25, 19, 47, 22, 150, time.UTC)},
|
|
}
|
|
|
|
res := MakeTree(comments, "+active", 0)
|
|
assert.Equal(t, "2", res.Nodes[0].Comment.ID)
|
|
t.Log(res.Nodes[0].Comment.ID, res.Nodes[0].tsModified)
|
|
|
|
res = MakeTree(comments, "-active", 0)
|
|
t.Log(res.Nodes[0].Comment.ID, res.Nodes[0].tsModified)
|
|
assert.Equal(t, "1", res.Nodes[0].Comment.ID)
|
|
|
|
res = MakeTree(comments, "+time", 0)
|
|
t.Log(res.Nodes[0].Comment.ID, res.Nodes[0].tsModified)
|
|
assert.Equal(t, "1", res.Nodes[0].Comment.ID)
|
|
|
|
res = MakeTree(comments, "-time", 0)
|
|
assert.Equal(t, "6", res.Nodes[0].Comment.ID)
|
|
|
|
res = MakeTree(comments, "score", 0)
|
|
assert.Equal(t, "4", res.Nodes[0].Comment.ID)
|
|
assert.Equal(t, "3", res.Nodes[1].Comment.ID)
|
|
assert.Equal(t, "6", res.Nodes[2].Comment.ID)
|
|
assert.Equal(t, "1", res.Nodes[3].Comment.ID)
|
|
|
|
res = MakeTree(comments, "+score", 0)
|
|
assert.Equal(t, "4", res.Nodes[0].Comment.ID)
|
|
|
|
res = MakeTree(comments, "-score", 0)
|
|
assert.Equal(t, "2", res.Nodes[0].Comment.ID)
|
|
assert.Equal(t, "1", res.Nodes[1].Comment.ID)
|
|
assert.Equal(t, "3", res.Nodes[2].Comment.ID)
|
|
assert.Equal(t, "6", res.Nodes[3].Comment.ID)
|
|
|
|
res = MakeTree(comments, "undefined", 0)
|
|
t.Log(res.Nodes[0].Comment.ID, res.Nodes[0].tsModified)
|
|
assert.Equal(t, "1", res.Nodes[0].Comment.ID)
|
|
}
|
|
|
|
func BenchmarkTree(b *testing.B) {
|
|
comments := []store.Comment{}
|
|
data, err := ioutil.ReadFile("testfile.json")
|
|
assert.Nil(b, err)
|
|
err = json.Unmarshal(data, &comments)
|
|
assert.Nil(b, err)
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
res := MakeTree(comments, "time", 0)
|
|
assert.NotNil(b, res)
|
|
}
|
|
}
|
|
|
|
const expJSON = `{
|
|
"comments": [
|
|
{
|
|
"comment": {
|
|
"id": "1",
|
|
"pid": "",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:46:01Z"
|
|
},
|
|
"replies": [
|
|
{
|
|
"comment": {
|
|
"id": "11",
|
|
"pid": "1",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:46:11Z"
|
|
}
|
|
},
|
|
{
|
|
"comment": {
|
|
"id": "12",
|
|
"pid": "1",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:46:12Z"
|
|
}
|
|
},
|
|
{
|
|
"comment": {
|
|
"id": "13",
|
|
"pid": "1",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:46:13Z"
|
|
},
|
|
"replies": [
|
|
{
|
|
"comment": {
|
|
"id": "131",
|
|
"pid": "13",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:46:31Z"
|
|
}
|
|
},
|
|
{
|
|
"comment": {
|
|
"id": "132",
|
|
"pid": "13",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:46:32Z"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"comment": {
|
|
"id": "14",
|
|
"pid": "1",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:46:14Z"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"comment": {
|
|
"id": "2",
|
|
"pid": "",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:47:02Z"
|
|
},
|
|
"replies": [
|
|
{
|
|
"comment": {
|
|
"id": "21",
|
|
"pid": "2",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:47:21Z"
|
|
}
|
|
},
|
|
{
|
|
"comment": {
|
|
"id": "22",
|
|
"pid": "2",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:47:22Z"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"comment": {
|
|
"id": "4",
|
|
"pid": "",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:47:22Z"
|
|
}
|
|
},
|
|
{
|
|
"comment": {
|
|
"id": "3",
|
|
"pid": "",
|
|
"text": "",
|
|
"user": {
|
|
"name": "",
|
|
"id": "",
|
|
"picture": "",
|
|
"admin": false
|
|
},
|
|
"locator": {
|
|
"site": "site",
|
|
"url": "url"
|
|
},
|
|
"score": 0,
|
|
"votes": null,
|
|
"time": "2017-12-25T19:47:22Z"
|
|
}
|
|
}
|
|
],
|
|
"info": {
|
|
"url": "url",
|
|
"count": 12,
|
|
"first_time": "2017-12-25T19:46:01Z",
|
|
"last_time": "2017-12-25T19:47:22Z"
|
|
}
|
|
}
|
|
`
|
|
|
|
func cleanFormatting(expected, actual string) (string, string) {
|
|
reSpaces := regexp.MustCompile(`[\s\p{Zs}]{2,}`)
|
|
|
|
expected = strings.Replace(expected, "\n", " ", -1)
|
|
expected = strings.Replace(expected, "\t", " ", -1)
|
|
expected = reSpaces.ReplaceAllString(expected, " ")
|
|
|
|
actual = strings.Replace(actual, "\n", " ", -1)
|
|
actual = reSpaces.ReplaceAllString(actual, " ")
|
|
return expected, actual
|
|
}
|