Support GET /who?sort=key&order=1
parent
36c4ae520d
commit
de1a426e08
48
view/who.go
48
view/who.go
|
|
@ -1,9 +1,11 @@
|
||||||
package view
|
package view
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"local/dndex/storage"
|
"local/dndex/storage"
|
||||||
"local/dndex/storage/entity"
|
"local/dndex/storage/entity"
|
||||||
|
|
@ -14,9 +16,15 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/buger/jsonparser"
|
"github.com/buger/jsonparser"
|
||||||
|
"github.com/iancoleman/orderedmap"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
querySort = "sort"
|
||||||
|
queryOrder = "order"
|
||||||
|
)
|
||||||
|
|
||||||
func who(g storage.Graph, w http.ResponseWriter, r *http.Request) error {
|
func who(g storage.Graph, w http.ResponseWriter, r *http.Request) error {
|
||||||
namespace, err := getNamespace(r)
|
namespace, err := getNamespace(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -74,9 +82,30 @@ func whoGet(namespace string, g storage.Graph, w http.ResponseWriter, r *http.Re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enc := json.NewEncoder(w)
|
b, err := json.MarshalIndent(one, "", " ")
|
||||||
enc.SetIndent("", " ")
|
if err != nil {
|
||||||
return enc.Encode(one)
|
return err
|
||||||
|
}
|
||||||
|
if _, ok := r.URL.Query()[querySort]; ok {
|
||||||
|
m := bson.M{}
|
||||||
|
if err := json.Unmarshal(b, &m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ones := make([]entity.One, len(one.Connections))
|
||||||
|
i := 0
|
||||||
|
for _, v := range one.Connections {
|
||||||
|
ones[i] = v
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
m[entity.Connections] = sortOnesObject(ones, r)
|
||||||
|
b, err = json.MarshalIndent(m, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(w, bytes.NewReader(b))
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func whoPut(namespace string, g storage.Graph, w http.ResponseWriter, r *http.Request) error {
|
func whoPut(namespace string, g storage.Graph, w http.ResponseWriter, r *http.Request) error {
|
||||||
|
|
@ -245,12 +274,21 @@ func getID(r *http.Request) (string, error) {
|
||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sortOnesObject(ones []entity.One, r *http.Request) interface{} {
|
||||||
|
ones = sortOnes(ones, r)
|
||||||
|
m := orderedmap.New()
|
||||||
|
for _, one := range ones {
|
||||||
|
m.Set(one.Name, one)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
func sortOnes(ones []entity.One, r *http.Request) []entity.One {
|
func sortOnes(ones []entity.One, r *http.Request) []entity.One {
|
||||||
sorting := sanitize(r.URL.Query().Get("sort"))
|
sorting := sanitize(r.URL.Query().Get(querySort))
|
||||||
if sorting == "" {
|
if sorting == "" {
|
||||||
sorting = entity.Modified
|
sorting = entity.Modified
|
||||||
}
|
}
|
||||||
order := sanitize(r.URL.Query().Get("order"))
|
order := sanitize(r.URL.Query().Get(queryOrder))
|
||||||
if order == "" {
|
if order == "" {
|
||||||
order = "-1"
|
order = "-1"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import (
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -165,6 +167,49 @@ func TestWho(t *testing.T) {
|
||||||
t.Logf("POST GET:\n%s", b)
|
t.Logf("POST GET:\n%s", b)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("get sorted type asc/desc", func(t *testing.T) {
|
||||||
|
for _, order := range []string{"1", "-1"} {
|
||||||
|
reset()
|
||||||
|
want := ones[len(ones)-1]
|
||||||
|
r := httptest.NewRequest(http.MethodGet, "/who?namespace=col&light&sort=type&order="+order+"&id="+want.Name, nil)
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
if w.Code != http.StatusOK {
|
||||||
|
t.Fatalf("%d: %s", w.Code, w.Body.Bytes())
|
||||||
|
}
|
||||||
|
o := entity.One{}
|
||||||
|
if err := json.Unmarshal(w.Body.Bytes(), &o); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(o.Connections) < 5 {
|
||||||
|
t.Fatal(len(o.Connections))
|
||||||
|
}
|
||||||
|
if len(o.Connections) != len(want.Connections) {
|
||||||
|
t.Fatal(len(want.Connections), len(o.Connections))
|
||||||
|
}
|
||||||
|
titles := []string{}
|
||||||
|
for _, v := range want.Connections {
|
||||||
|
if len(v.Type) == 0 {
|
||||||
|
t.Fatal(v.Type)
|
||||||
|
}
|
||||||
|
titles = append(titles, v.Type)
|
||||||
|
}
|
||||||
|
sort.Strings(titles)
|
||||||
|
if order == "-1" {
|
||||||
|
for i := 0; i < len(titles)/2; i++ {
|
||||||
|
tmp := titles[len(titles)-1-i]
|
||||||
|
titles[len(titles)-1-i] = titles[i]
|
||||||
|
titles[i] = tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pattern := strings.Join(titles, ".*")
|
||||||
|
pattern = strings.Replace(pattern, "-", ".", -1)
|
||||||
|
if !regexp.MustCompile(pattern).Match(bytes.Replace(w.Body.Bytes(), []byte("\n"), []byte(" "), -1)) {
|
||||||
|
t.Fatal(order, pattern, string(w.Body.Bytes()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("put fake", func(t *testing.T) {
|
t.Run("put fake", func(t *testing.T) {
|
||||||
reset()
|
reset()
|
||||||
iwant := want
|
iwant := want
|
||||||
|
|
@ -486,7 +531,8 @@ func TestWho(t *testing.T) {
|
||||||
|
|
||||||
t.Run("delete connection 1 of 1 ok", func(t *testing.T) {
|
t.Run("delete connection 1 of 1 ok", func(t *testing.T) {
|
||||||
reset()
|
reset()
|
||||||
r := httptest.NewRequest(http.MethodDelete, fmt.Sprintf("/who?namespace=col&id=%s&connection=%s", want.Name, want.Peers()[0]), nil)
|
deleted := want.Peers()[0]
|
||||||
|
r := httptest.NewRequest(http.MethodDelete, fmt.Sprintf("/who?namespace=col&id=%s&connection=%s", want.Name, deleted), nil)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
handler.ServeHTTP(w, r)
|
handler.ServeHTTP(w, r)
|
||||||
if w.Code != http.StatusOK {
|
if w.Code != http.StatusOK {
|
||||||
|
|
@ -503,8 +549,8 @@ func TestWho(t *testing.T) {
|
||||||
if err := json.Unmarshal(w.Body.Bytes(), &o); err != nil {
|
if err := json.Unmarshal(w.Body.Bytes(), &o); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if _, ok := o.Connections[want.Peers()[0]]; ok {
|
if _, ok := o.Connections[deleted]; ok {
|
||||||
t.Fatal(want.Peers()[0], o.Connections)
|
t.Fatal(deleted, o.Connections)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -590,9 +636,10 @@ func fillDB(t *testing.T, g storage.Graph) []entity.One {
|
||||||
ones := make([]entity.One, 13)
|
ones := make([]entity.One, 13)
|
||||||
for i := range ones {
|
for i := range ones {
|
||||||
ones[i] = randomOne()
|
ones[i] = randomOne()
|
||||||
if i > 0 {
|
for j := 0; j < i; j++ {
|
||||||
ones[i].Connections[ones[i-1].Name] = entity.One{
|
ones[i].Connections[ones[j].Name] = entity.One{
|
||||||
Name: ones[i-1].Name,
|
Name: ones[j].Name,
|
||||||
|
Type: ones[j].Type,
|
||||||
Relationship: ":D",
|
Relationship: ":D",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue