package main import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "path" "strings" "testing" ) func TestServerRoutes(t *testing.T) { server := NewServer(t.TempDir()) if err := server.Routes(); err != nil { t.Fatal(err) } ensureAndWrite(server.diskMediaPath("id"), []byte("hi")) ensureAndWrite(server.diskMediaPath("delid"), []byte("hi")) ensureAndWrite(server.diskFilePath("getfid"), []byte("getfid body")) ensureAndWrite(server.diskFilePath("putfid"), []byte("initial putfid body")) ensureAndWrite(server.diskFilePath("delfid"), []byte("delfid body")) ensureAndWrite(path.Join(server.root, "index.html"), []byte("mom")) server.tree().Put("putfid", Branch{}) server.tree().Put("delfid", Branch{Title: "delfid title"}) server.tree().Put("getfid", Branch{Title: "getfid title"}) cases := map[string]struct { path string method string body string want string }{ "v0: /: get": { path: "/", method: http.MethodGet, want: "mom", }, "v0: search: get": { path: "/api/v0/search?q=getf%20bod", method: http.MethodGet, want: `["getfid"]`, }, "v0: tree: get pretty": { path: "/api/v0/tree?pretty", method: http.MethodGet, want: `"getfid":{"Children":{`, }, "v0: tree: get": { path: "/api/v0/tree", method: http.MethodGet, want: `":{"Title":"getfid title",`, }, "v0: media: post": { path: "/api/v0/media", method: http.MethodPost, want: `{"data":{"filePath":"/api/v0/media/`, }, "v0: media id: del": { path: "/api/v0/media/delid", method: http.MethodDelete, }, "v0: media id: get": { path: "/api/v0/media/id", method: http.MethodGet, want: "hi", }, "v0: files: post": { path: "/api/v0/files", method: http.MethodPost, }, "v0: files id: get": { path: "/api/v0/files/getfid", method: http.MethodGet, want: "getfid body", }, "v0: files id: put": { path: "/api/v0/files/putfid", method: http.MethodPut, body: "putfid body", }, "v0: files id: del": { path: "/api/v0/files/delfid", method: http.MethodDelete, }, } for name, d := range cases { c := d t.Run(name, func(t *testing.T) { r := httptest.NewRequest(c.method, c.path, strings.NewReader(c.body)) w := httptest.NewRecorder() server.ServeHTTP(w, r) if w.Code == http.StatusNotFound { t.Fatal(w) } if w.Code != http.StatusOK { t.Fatal(w) } if len(c.want) > 0 && !strings.Contains(string(w.Body.Bytes()), c.want) { t.Fatal(w) } t.Logf("%s %s (%+v) => %s", c.method, c.path, w.Header(), w.Body.Bytes()) }) } } func TestServerPutTreeGetFile(t *testing.T) { server := NewServer(t.TempDir()) if err := server.Routes(); err != nil { t.Fatal(err) } server.tree().Put("my pid", Branch{}) var id string t.Run("put to create an id", func(t *testing.T) { r := httptest.NewRequest(http.MethodPut, "/my-put-id", strings.NewReader("body")) r.Header.Set("Title", "my put title") r.Header.Set("PID", "my pid") w := httptest.NewRecorder() if err := server.apiV0FilesIDHandler(w, r); err != nil { t.Fatal(err) } if w.Code != http.StatusOK { t.Fatal(w) } var resp struct { Data struct { FilePath string `json:"filePath"` } `json:"data"` } if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { t.Fatal(err) } if path.Base(resp.Data.FilePath) != "my-put-id" { t.Fatal(resp.Data.FilePath) } }) t.Run("post", func(t *testing.T) { r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader("body")) r.Header.Set("Title", "my title") r.Header.Set("PID", "my pid") w := httptest.NewRecorder() if err := server.apiV0FilesHandler(w, r); err != nil { t.Fatal(err) } if w.Code != http.StatusOK { t.Fatal(w) } var resp struct { Data struct { FilePath string `json:"filePath"` } `json:"data"` } if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { t.Fatal(err) } id = path.Base(resp.Data.FilePath) }) t.Run("tree", func(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/", nil) w := httptest.NewRecorder() if err := server.apiV0TreeHandler(w, r); err != nil { t.Fatal(err) } if w.Code != http.StatusOK { t.Fatal(w) } if !bytes.Contains(w.Body.Bytes(), []byte(`{"Title":"my title","Deleted":false,"Updated":"`)) { t.Fatal(w) } }) t.Run("get", func(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/"+id, nil) w := httptest.NewRecorder() if err := server.apiV0FilesIDHandler(w, r); err != nil { t.Fatal(err) } if w.Code != http.StatusOK { t.Fatal(w) } if !bytes.Contains(w.Body.Bytes(), []byte(`body`)) { t.Fatal(w) } if title := w.Header().Get("Title"); title != "my title" { t.Fatal(title) } else if pid := w.Header().Get("PID"); pid != "my pid" { t.Fatal(pid) } }) }