Trace is sortable by field and asc-desc

master
Bel LaPointe 2020-07-24 20:35:13 -06:00
parent dc5729f20c
commit 95555f46ec
3 changed files with 125 additions and 5 deletions

View File

@ -48,7 +48,6 @@ func jsonHandler(g storage.Graph) http.Handler {
mux.HandleFunc(route.path, func(w http.ResponseWriter, r *http.Request) {
if auth {
if err := Auth(g, w, r); err != nil {
log.Println(err)
return
}
}

View File

@ -220,11 +220,14 @@ func sortOnes(ones []entity.One, r *http.Request) []entity.One {
}
asc := order != "-1"
sort.Slice(ones, func(i, j int) bool {
ib, _ := bson.Marshal(ones[i])
jb, _ := bson.Marshal(ones[j])
if sorting == entity.Name {
return (asc && ones[i].Name < ones[j].Name) || (!asc && ones[i].Name > ones[j].Name)
}
ib, _ := json.Marshal(ones[i])
jb, _ := json.Marshal(ones[j])
var im, jm bson.M
bson.Unmarshal(ib, &im)
bson.Unmarshal(jb, &jm)
json.Unmarshal(ib, &im)
json.Unmarshal(jb, &jm)
iv, _ := im[sorting]
jv, _ := jm[sorting]
is := fmt.Sprint(iv)

View File

@ -11,6 +11,7 @@ import (
"local/dndex/storage/entity"
"net/http"
"net/http/httptest"
"net/url"
"os"
"strings"
"testing"
@ -252,6 +253,32 @@ func TestWho(t *testing.T) {
}
t.Logf("%+v", v)
})
t.Run("trace real sorted asc/desc name", func(t *testing.T) {
for _, order := range []string{"1", "-1"} {
r := httptest.NewRequest(http.MethodTrace, "/who?namespace=col&sort=name&order="+order, nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, r)
if w.Code != http.StatusOK {
t.Fatalf("%d: %s", w.Code, w.Body.Bytes())
}
var v []string
if err := json.Unmarshal(w.Body.Bytes(), &v); err != nil {
t.Fatalf("%v: %s", err, w.Body.Bytes())
}
if len(v) < 5 {
t.Fatal(len(v))
}
for i := range v {
if i == 0 {
continue
}
if (v[i] < v[i-1] && order == "1") || (v[i] > v[i-1] && order == "-1") {
t.Fatalf("not sorted: %s: %+v", order, v)
}
}
}
})
}
func fillDB(t *testing.T, g storage.Graph) []entity.One {
@ -296,3 +323,94 @@ func randomOne() entity.One {
Connections: map[string]entity.One{},
}
}
//func sortOnes(ones []entity.One, r *http.Request) []entity.One {
func TestSortOnes(t *testing.T) {
oneA := entity.One{Name: "A", Title: "c", Modified: 2}
oneB := entity.One{Name: "B", Title: "b", Modified: 1}
oneC := entity.One{Name: "C", Title: "a", Modified: 3}
cases := map[string]struct {
ones []entity.One
sort string
order string
test func(entity.One, entity.One) bool
}{
"nothing to sort": {},
"all the same": {
ones: []entity.One{oneA, oneA, oneA},
test: func(a, b entity.One) bool { return fmt.Sprint(a) == fmt.Sprint(b) },
},
"default: modified desc, but already ordered": {
ones: []entity.One{oneC, oneB, oneA},
test: func(a, b entity.One) bool { return a.Modified >= b.Modified },
},
"default: modified desc": {
ones: []entity.One{oneA, oneB, oneC},
test: func(a, b entity.One) bool { return a.Modified >= b.Modified },
},
"default=modified set=desc": {
ones: []entity.One{oneA, oneB, oneC},
order: "-1",
test: func(a, b entity.One) bool { return a.Modified >= b.Modified },
},
"set=modified default=desc": {
ones: []entity.One{oneA, oneB, oneC},
sort: entity.Modified,
test: func(a, b entity.One) bool { return a.Modified >= b.Modified },
},
"set=modified set=asc": {
ones: []entity.One{oneA, oneB, oneC},
sort: entity.Modified,
order: "1",
test: func(a, b entity.One) bool { return a.Modified <= b.Modified },
},
"set=title set=desc": {
ones: []entity.One{oneA, oneB, oneC},
sort: entity.Title,
order: "-1",
test: func(a, b entity.One) bool { return a.Title >= b.Title },
},
"set=title set=asc": {
ones: []entity.One{oneA, oneB, oneC},
sort: entity.Title,
order: "1",
test: func(a, b entity.One) bool { return a.Title <= b.Title },
},
"set=name set=desc": {
ones: []entity.One{oneA, oneB, oneC},
sort: entity.Name,
order: "-1",
test: func(a, b entity.One) bool { return a.Name >= b.Name },
},
"set=name set=asc": {
ones: []entity.One{oneA, oneB, oneC},
sort: entity.Name,
order: "1",
test: func(a, b entity.One) bool { return a.Name <= b.Name },
},
}
for name, d := range cases {
c := d
t.Run(name, func(t *testing.T) {
q := url.Values{}
q.Set("sort", c.sort)
q.Set("order", c.order)
url := url.URL{
Path: "/",
RawQuery: q.Encode(),
}
r := httptest.NewRequest("GET", url.String(), nil)
ones := sortOnes(c.ones, r)
for i := range ones {
if i == 0 {
continue
}
if ok := c.test(ones[i-1], ones[i]); !ok {
t.Fatal(ok, ones[i-1], ones[i])
}
}
})
}
}