package view import ( "context" "encoding/json" "local/dndex/config" "local/dndex/storage" "net/http" "net/http/httptest" "net/url" "os" "testing" "time" ) func TestGetNamespace(t *testing.T) { os.Args = os.Args[:1] cases := map[string]struct { url string want string invalid bool }{ "no query param, not files, should fail": { url: "/", invalid: true, }, "empty query param, not files, should fail": { url: "/a?namespace=", invalid: true, }, "query param, not files": { url: "/a?namespace=OK", want: "OK", }, "files, no query param": { url: config.New().FilePrefix + "/OK", want: "OK", }, } for name, d := range cases { c := d t.Run(name, func(t *testing.T) { c.url = "http://host.tld:80" + c.url uri, err := url.Parse(c.url) if err != nil { t.Fatal(err) } ns, err := getNamespace(&http.Request{URL: uri}) if err != nil && !c.invalid { t.Fatal(c.invalid, err) } else if err == nil && ns != c.want { t.Fatal(c.want, ns) } authns, err := getAuthNamespace(&http.Request{URL: uri}) if err != nil && !c.invalid { t.Fatal(c.invalid, err) } else if err == nil && authns != c.want+"."+AuthKey { t.Fatal(c.want+"."+AuthKey, authns) } }) } } func TestRateLimited(t *testing.T) { os.Args = os.Args[:1] os.Setenv("SYS_RPS", "10") foo := rateLimited(func(w http.ResponseWriter, r *http.Request) {}) ok := 0 tooMany := 0 for i := 0; i < 20; i++ { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "/", nil) ctx, can := context.WithTimeout(r.Context(), time.Millisecond*50) defer can() r = r.WithContext(ctx) foo(w, r) switch w.Code { case http.StatusOK: ok += 1 case http.StatusTooManyRequests: tooMany += 1 default: t.Fatal("unexpected status", w.Code) } } if ok < 9 || ok > 11 { t.Fatal(ok, tooMany) } } func TestVersion(t *testing.T) { t.Run("no version set", func(t *testing.T) { w := httptest.NewRecorder() if err := version(storage.RateLimitedGraph{}, w, nil); err != nil { t.Fatal(err) } var resp struct { Version string `json:"version"` } if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { t.Fatal(err) } else if resp.Version != "" { t.Fatal(resp) } }) t.Run("version set", func(t *testing.T) { GitCommit = "my-git-commit" w := httptest.NewRecorder() if err := version(storage.RateLimitedGraph{}, w, nil); err != nil { t.Fatal(err) } var resp struct { Version string `json:"version"` } if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { t.Fatal(err) } else if resp.Version != "my-git-commit" { t.Fatal(resp) } }) } func TestDelay(t *testing.T) { defer func() { os.Setenv("DELAY", "0ms") }() os.Args = os.Args[:1] os.Setenv("DELAY", "100ms") r := httptest.NewRequest("GET", "/", nil) w := httptest.NewRecorder() start := time.Now() if err := delay(w, r); err != nil { t.Fatal(err) } if since := time.Since(start); since < time.Millisecond*100 { t.Fatal(since) } r = httptest.NewRequest("GET", "/", nil) ctx, can := context.WithCancel(r.Context()) can() r = r.WithContext(ctx) w = httptest.NewRecorder() start = time.Now() if err := delay(w, r); err == nil { t.Fatal(err) } if since := time.Since(start); since > time.Millisecond*99 { t.Fatal(since) } }