From 95555f46ec4d99025adef10e3a527e5e2dff420c Mon Sep 17 00:00:00 2001 From: Bel LaPointe Date: Fri, 24 Jul 2020 20:35:13 -0600 Subject: [PATCH] Trace is sortable by field and asc-desc --- view/json.go | 1 - view/who.go | 11 +++-- view/who_test.go | 118 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 5 deletions(-) diff --git a/view/json.go b/view/json.go index b5f7c9e..f076ce0 100644 --- a/view/json.go +++ b/view/json.go @@ -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 } } diff --git a/view/who.go b/view/who.go index 886136b..9427b4f 100644 --- a/view/who.go +++ b/view/who.go @@ -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) diff --git a/view/who_test.go b/view/who_test.go index eab0a68..0050908 100644 --- a/view/who_test.go +++ b/view/who_test.go @@ -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]) + } + } + }) + } +}