add /count request

This commit is contained in:
eugene
2017-12-22 13:24:29 -06:00
parent e62881b30a
commit 983606ecd6
5 changed files with 55 additions and 16 deletions
+8 -7
View File
@@ -8,7 +8,7 @@ Comment engine
- `GET /login/{provider}?from=http://url` - perform "social" login with one of supported providers and redirect to `url`
- `GET /logout` - logout
- `GET /user` - get user info, _auth required_
- `GET /api/v1/user` - get user info, _auth required_
```
type User struct {
@@ -24,7 +24,7 @@ _currently supported providers are `google` and `github`_
### Commenting
- `POST /comment` - add a comment. _auth required_
- `POST /api/v1/comment` - add a comment. _auth required_
```
type Comment struct {
@@ -44,8 +44,9 @@ type Locator struct {
}
```
- `GET /find?url=post-url` - find all comments for given post returns list of `Comment`
- `GET /last/{max}` - get last `{max}` comments
- `GET /id/{id}` - get comment by `id`
- `PUT /vote/{id}?url=post-url&vote=1` - vote for comment. `vote`=1 will increase score, -1 decreases. _auth required_
- `DELETE /comment/{id}` - delete comment by `id`. _auth and admin required_
- `GET /api/v1/find?url=post-url` - find all comments for given post returns list of `Comment`
- `GET /api/v1/last/{max}` - get last `{max}` comments
- `GET /api/v1/id/{id}` - get comment by `id`
- `GET /api/v1/count?url=post-url` - get comment's count for `{url}`
- `PUT /api/v1/vote/{id}?url=post-url&vote=1` - vote for comment. `vote`=1 will increase score, -1 decreases. _auth required_
- `DELETE /api/v1/comment/{id}?url=post-url` - delete comment by `id`. _auth and admin required_
+22 -8
View File
@@ -41,15 +41,18 @@ func (s *Server) Run() {
router.Get("/login/github", s.AuthGithub.LoginHandler)
router.Get("/auth/github", s.AuthGithub.AuthHandler)
router.Get("/find", s.getURLComments)
router.Get("/id/{id}", s.getByID)
router.Get("/last/{max}", s.getLastComments)
router.Route("/api/v1", func(rapi chi.Router) {
rapi.Get("/find", s.getURLComments)
rapi.Get("/id/{id}", s.getByID)
rapi.Get("/last/{max}", s.getLastComments)
rapi.Get("/count", s.getCountCtrl)
router.With(Auth(s.SessionStore, s.Admins)).Group(func(r chi.Router) {
r.Post("/comment", s.createCommentCtrl)
r.Get("/user", s.getUserInfo)
r.Put("/vote/{id}", s.voteCtrl)
r.With(AdminOnly).Delete("/comment/{id}", s.deleteCommentCtrl)
rapi.With(Auth(s.SessionStore, s.Admins)).Group(func(r chi.Router) {
r.Post("/comment", s.createCommentCtrl)
r.Get("/user", s.getUserInfo)
r.Put("/vote/{id}", s.voteCtrl)
r.With(AdminOnly).Delete("/comment/{id}", s.deleteCommentCtrl)
})
})
log.Fatal(http.ListenAndServe(":8080", router))
@@ -179,6 +182,17 @@ func (s *Server) getUserInfo(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, user)
}
// GET /count?url=post-url
func (s *Server) getCountCtrl(w http.ResponseWriter, r *http.Request) {
url := r.URL.Query().Get("url")
count, err := s.Store.Count(store.Locator{URL: url})
if err != nil {
httpError(w, r, http.StatusBadRequest, err, "can't get count")
return
}
render.JSON(w, r, JSON{"count": count, "url": url})
}
// PUT /vote/{id}?url=post-url&vote=1
func (s *Server) voteCtrl(w http.ResponseWriter, r *http.Request) {
+14
View File
@@ -243,6 +243,20 @@ func (b *BoltDB) Vote(locator Locator, commentID int64, userID string, val bool)
return comment, err
}
func (b *BoltDB) Count(locator Locator) (count int, err error) {
err = b.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte(locator.URL))
if bucket == nil {
return errors.Errorf("no bucket %s in store", locator.URL)
}
count = bucket.Stats().KeyN
return nil
})
return count, err
}
func (b *BoltDB) keyFromComment(comment Comment) []byte {
return []byte(fmt.Sprintf("%22d", comment.ID))
}
+10 -1
View File
@@ -31,7 +31,7 @@ func TestBoltDB_Delete(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, 2, len(res))
err = b.Delete("https://radio-t.com", res[0].ID)
err = b.Delete(Locator{URL: "https://radio-t.com"}, res[0].ID)
assert.Nil(t, err)
res, err = b.Find(Request{Locator: Locator{URL: "https://radio-t.com"}})
@@ -95,6 +95,15 @@ func TestBoltDB_Vote(t *testing.T) {
assert.Equal(t, 1, res[0].Score)
}
func TestBoltDB_Count(t *testing.T) {
defer os.Remove(testDb)
b := prep(t)
c, err := b.Count(Locator{URL: "https://radio-t.com"})
assert.Nil(t, err)
assert.Equal(t, 2, c)
}
// makes new boltdb, put two records
func prep(t *testing.T) *BoltDB {
b, err := NewBoltDB(testDb)
+1
View File
@@ -46,4 +46,5 @@ type Interface interface {
Last(locator Locator, max int) ([]Comment, error)
Get(locator Locator, id int64) (Comment, error)
Vote(locator Locator, commentID int64, userID string, val bool) (Comment, error)
Count(locator Locator) (int, error)
}