From 58cf373627948216125bc3138d9b27c2b445a14d Mon Sep 17 00:00:00 2001 From: Umputun Date: Thu, 10 May 2018 01:10:36 -0500 Subject: [PATCH] more tests --- app/rest/api/admin_test.go | 31 +++++++++++++++++++++++++++++++ app/rest/api/rest.go | 6 ------ app/rest/api/rest_test.go | 20 ++++++++++++++++++++ app/store/bolt_test.go | 7 ++++--- app/store/comment.go | 2 +- app/store/service.go | 14 ++++++++++++-- app/store/service_test.go | 32 +++++++++++++++++++++----------- 7 files changed, 89 insertions(+), 23 deletions(-) diff --git a/app/rest/api/admin_test.go b/app/rest/api/admin_test.go index c5597ac7..3ee4fb18 100644 --- a/app/rest/api/admin_test.go +++ b/app/rest/api/admin_test.go @@ -141,6 +141,37 @@ func TestAdmin_Block(t *testing.T) { assert.Equal(t, false, j["block"]) } +func TestAdmin_BlockedList(t *testing.T) { + srv, port := prep(t) + assert.NotNil(t, srv) + defer cleanup(srv) + + client := http.Client{} + + // block user1 + req, err := http.NewRequest(http.MethodPut, + fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/user/%s?site=radio-t&block=%d", port, "user1", 1), nil) + assert.Nil(t, err) + _, err = client.Do(req) + require.Nil(t, err) + + // block user2 + req, err = http.NewRequest(http.MethodPut, + fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/user/%s?site=radio-t&block=%d", port, "user2", 1), nil) + assert.Nil(t, err) + _, err = client.Do(req) + require.Nil(t, err) + + res, code := get(t, fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/blocked?site=radio-t", port)) + require.Equal(t, 200, code, res) + users := []store.BlockedUser{} + err = json.Unmarshal([]byte(res), &users) + assert.Nil(t, err) + assert.Equal(t, 2, len(users), "two users blocked") + assert.Equal(t, "user1", users[0].ID) + assert.Equal(t, "user2", users[1].ID) +} + func TestAdmin_Export(t *testing.T) { srv, port := prep(t) assert.NotNil(t, srv) diff --git a/app/rest/api/rest.go b/app/rest/api/rest.go index c2722a2a..70684735 100644 --- a/app/rest/api/rest.go +++ b/app/rest/api/rest.go @@ -140,12 +140,6 @@ func (s *Rest) createCommentCtrl(w http.ResponseWriter, r *http.Request) { comment.PrepareUntrusted() // clean all fields user not suppoed to set comment.User = user comment.User.IP = strings.Split(r.RemoteAddr, ":")[0] - - if err = s.DataService.ValidateComment(&comment); err != nil { - rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "invalid comment") - return - } - comment.Text = string(blackfriday.Run([]byte(comment.Text), blackfriday.WithExtensions(mdExt))) log.Printf("[DEBUG] create comment %+v", comment) diff --git a/app/rest/api/rest_test.go b/app/rest/api/rest_test.go index 551f5496..44017b2a 100644 --- a/app/rest/api/rest_test.go +++ b/app/rest/api/rest_test.go @@ -57,6 +57,26 @@ func TestServer_Create(t *testing.T) { assert.True(t, len(c["id"].(string)) > 8) } +func TestServer_CreateTooBig(t *testing.T) { + srv, port := prep(t) + require.NotNil(t, srv) + defer cleanup(srv) + + longComment := fmt.Sprintf(`{"text": "%6000s", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`, "blah") + r := strings.NewReader(longComment) + resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/comment", port), "application/json", r) + assert.Nil(t, err) + assert.Equal(t, http.StatusInternalServerError, resp.StatusCode) + b, err := ioutil.ReadAll(resp.Body) + assert.Nil(t, err) + c := JSON{} + err = json.Unmarshal(b, &c) + assert.Nil(t, err) + + assert.Equal(t, "comment text exceeded max allowed size", c["error"]) + assert.Equal(t, "can't save comment", c["details"]) +} + func TestServer_Preview(t *testing.T) { srv, port := prep(t) require.NotNil(t, srv) diff --git a/app/store/bolt_test.go b/app/store/bolt_test.go index 7896f02a..f4ab80da 100644 --- a/app/store/bolt_test.go +++ b/app/store/bolt_test.go @@ -18,7 +18,7 @@ func TestBoltDB_CreateAndFind(t *testing.T) { res, err := b.Find(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, "time") assert.Nil(t, err) assert.Equal(t, 2, len(res)) - assert.Equal(t, `some text, link`, res[0].Text) + assert.Equal(t, `some text, link`, res[0].Text) assert.Equal(t, "user1", res[0].User.ID) t.Log(res[0].ID) @@ -172,6 +172,7 @@ func TestBoltDB_List(t *testing.T) { // add one more for https://radio-t.com/2 comment := Comment{ + ID: "12345", Text: `some text, link`, Timestamp: time.Date(2017, 12, 20, 15, 18, 22, 0, time.Local), Locator: Locator{URL: "https://radio-t.com/2", SiteID: "radio-t"}, @@ -212,12 +213,12 @@ func TestBoltDB_GetForUser(t *testing.T) { } // makes new boltdb, put two records -func prep(t *testing.T) *Service { +func prep(t *testing.T) *BoltDB { os.Remove(testDb) boltStore, err := NewBoltDB(bolt.Options{}, BoltSite{FileName: "/tmp/test-remark.db", SiteID: "radio-t"}) assert.Nil(t, err) - b := &Service{Interface: boltStore} + b := boltStore comment := Comment{ ID: "id-1", diff --git a/app/store/comment.go b/app/store/comment.go index 28390096..e42097f4 100644 --- a/app/store/comment.go +++ b/app/store/comment.go @@ -24,7 +24,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"` + Edit *Edit `json:"edit,omitempty"` // pointer to have empty default in json response Deleted bool `json:"delete,omitempty"` } diff --git a/app/store/service.go b/app/store/service.go index 0b8c62e1..d2ed9fb9 100644 --- a/app/store/service.go +++ b/app/store/service.go @@ -15,6 +15,8 @@ type Service struct { MaxCommentSize int } +const defaultCommentMaxSize = 2000 + // Create prepares comment and forward to Interface.Create func (s *Service) Create(comment Comment) (commentID string, err error) { // fill ID and time if empty @@ -29,6 +31,9 @@ func (s *Service) Create(comment Comment) (commentID string, err error) { comment.Votes = make(map[string]bool) } + if err = s.ValidateComment(&comment); err != nil { + return "", err + } comment.Sanitize() // clear potentially dangerous js from all parts of comment comment.User.hashIP(s.Secret) // replace ip by hash @@ -101,6 +106,11 @@ func (s *Service) EditComment(locator Locator, commentID string, text string, ed comment.Text = text comment.Edit = &edit comment.Edit.Timestamp = time.Now() + + if err = s.ValidateComment(&comment); err != nil { + return comment, err + } + comment.Sanitize() err = s.Put(locator, comment) return comment, err @@ -121,7 +131,7 @@ func (s *Service) Counts(siteID string, postIDs []string) ([]PostInfo, error) { func (s *Service) ValidateComment(c *Comment) error { maxSize := s.MaxCommentSize if s.MaxCommentSize <= 0 { - maxSize = 2000 + maxSize = defaultCommentMaxSize } if c.Text == "" { return errors.New("empty comment text") @@ -130,7 +140,7 @@ func (s *Service) ValidateComment(c *Comment) error { return errors.New("comment text exceeded max allowed size") } if c.User.ID == "" || c.User.Name == "" { - return errors.New("empty user info") + return errors.Errorf("empty user info") } return nil } diff --git a/app/store/service_test.go b/app/store/service_test.go index c86af5d3..944b6556 100644 --- a/app/store/service_test.go +++ b/app/store/service_test.go @@ -1,6 +1,7 @@ package store import ( + "fmt" "os" "testing" "time" @@ -15,7 +16,7 @@ func TestService_CreateFromEmpty(t *testing.T) { b := Service{Interface: prep(t), Secret: "secret 123"} comment := Comment{ Text: "text", - User: User{IP: "192.168.1.1", ID: "user"}, + User: User{IP: "192.168.1.1", ID: "user", Name: "name"}, Locator: Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, } id, err := b.Create(comment) @@ -28,7 +29,8 @@ func TestService_CreateFromEmpty(t *testing.T) { assert.Equal(t, "text", res.Text) assert.True(t, time.Since(res.Timestamp).Seconds() < 1) assert.Equal(t, "user", res.User.ID) - assert.Equal(t, "9f41a4b2dca0c826f1aa2c69246347758a43eac1", res.User.IP) + assert.Equal(t, "name", res.User.Name) + assert.Equal(t, "23f97cf4d5c29ef788ca2bdd1c9e75656c0e4149", res.User.IP) assert.Equal(t, map[string]bool{}, res.Votes) } @@ -39,7 +41,7 @@ func TestService_CreateFromPartial(t *testing.T) { Text: "text", Timestamp: time.Date(2018, 3, 25, 16, 34, 33, 0, time.UTC), Votes: map[string]bool{"u1": true, "u2": false}, - User: User{IP: "192.168.1.1", ID: "user"}, + User: User{IP: "192.168.1.1", ID: "user", Name: "name"}, Locator: Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, } id, err := b.Create(comment) @@ -52,7 +54,8 @@ func TestService_CreateFromPartial(t *testing.T) { assert.Equal(t, "text", res.Text) assert.Equal(t, comment.Timestamp, res.Timestamp) assert.Equal(t, "user", res.User.ID) - assert.Equal(t, "9f41a4b2dca0c826f1aa2c69246347758a43eac1", res.User.IP) + assert.Equal(t, "name", res.User.Name) + assert.Equal(t, "23f97cf4d5c29ef788ca2bdd1c9e75656c0e4149", res.User.IP) assert.Equal(t, comment.Votes, res.Votes) } @@ -60,10 +63,18 @@ func TestService_Vote(t *testing.T) { defer os.Remove(testDb) b := Service{Interface: prep(t)} + comment := Comment{ + Text: "text", + User: User{IP: "192.168.1.1", ID: "user", Name: "name"}, + Locator: Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, + } + _, err := b.Create(comment) + assert.NoError(t, err) + res, err := b.Last("radio-t", 0) t.Logf("%+v", res[0]) assert.Nil(t, err) - assert.Equal(t, 2, len(res)) + assert.Equal(t, 3, len(res)) assert.Equal(t, 0, res[0].Score) assert.Equal(t, map[string]bool{}, res[0].Votes, "no votes initially") @@ -77,14 +88,14 @@ func TestService_Vote(t *testing.T) { res, err = b.Last("radio-t", 0) assert.Nil(t, err) - assert.Equal(t, 2, len(res)) + assert.Equal(t, 3, len(res)) assert.Equal(t, 1, res[0].Score) _, err = b.Vote(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID, "user1", false) assert.Nil(t, err, "vote reset") res, err = b.Last("radio-t", 0) assert.Nil(t, err) - assert.Equal(t, 2, len(res)) + assert.Equal(t, 3, len(res)) assert.Equal(t, 0, res[0].Score) assert.Equal(t, map[string]bool{}, res[0].Votes, "vote reset ok") } @@ -170,10 +181,8 @@ func TestService_EditCommentDurationFailed(t *testing.T) { func TestService_ValidateComment(t *testing.T) { b := Service{MaxCommentSize: 2000} - longText := "" - for i := 0; i < 4000; i++ { - longText += "X" - } + longText := fmt.Sprintf("%4000s", "X") + tbl := []struct { inp Comment err error @@ -200,6 +209,7 @@ func TestService_Counts(t *testing.T) { // add one more for https://radio-t.com/2 comment := Comment{ + ID: "123456", Text: `some text, link`, Timestamp: time.Date(2017, 12, 20, 15, 18, 22, 0, time.Local), Locator: Locator{URL: "https://radio-t.com/2", SiteID: "radio-t"},