From 889894a73708a0730e3040ae1ddd0ffb64f3d0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torjus=20H=C3=A5kestad?= Date: Sun, 23 Jan 2022 17:22:16 +0100 Subject: [PATCH] Reorganize api tests --- api/http_test.go | 357 +++++++++++++++++++++++++---------------------- 1 file changed, 193 insertions(+), 164 deletions(-) diff --git a/api/http_test.go b/api/http_test.go index 68d5dc1..a826040 100644 --- a/api/http_test.go +++ b/api/http_test.go @@ -21,16 +21,17 @@ import ( ) func TestHandlers(t *testing.T) { - cfg := &gpaste.ServerConfig{ - SigningSecret: "abc123", - Store: &gpaste.ServerStoreConfig{ - Type: "memory", - }, - URL: "http://localhost:8080", - } - hs := api.NewHTTPServer(cfg) + //cfg := &gpaste.ServerConfig{ + // SigningSecret: "abc123", + // Store: &gpaste.ServerStoreConfig{ + // Type: "memory", + // }, + // URL: "http://localhost:8080", + //} + //hs := api.NewHTTPServer(cfg) - t.Run("HandlerIndex", func(t *testing.T) { + t.Run("index", func(t *testing.T) { + hs := newServer() rr := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/", nil) @@ -45,198 +46,226 @@ func TestHandlers(t *testing.T) { t.Errorf("Body does not match expected. Got %s want %s", body, expectedBody) } }) - t.Run("HandlerAPIFilePost", func(t *testing.T) { - rr := httptest.NewRecorder() - buf := &bytes.Buffer{} - mw := multipart.NewWriter(buf) - fw, err := mw.CreateFormFile("test", "test.txt") - if err != nil { - t.Fatalf("Unable to create form file: %s", err) - } - expectedData := "Test OMEGALUL PLS." - if _, err := io.WriteString(fw, expectedData); err != nil { - t.Fatalf("Unable to write body to buffer: %s", err) - } - mw.Close() + t.Run("api", func(t *testing.T) { + t.Run("file", func(t *testing.T) { + // POST /api/file + t.Run("POST", func(t *testing.T) { + hs := newServer() + rr := httptest.NewRecorder() + buf := &bytes.Buffer{} + mw := multipart.NewWriter(buf) + fw, err := mw.CreateFormFile("test", "test.txt") + if err != nil { + t.Fatalf("Unable to create form file: %s", err) + } + expectedData := "Test OMEGALUL PLS." + if _, err := io.WriteString(fw, expectedData); err != nil { + t.Fatalf("Unable to write body to buffer: %s", err) + } + mw.Close() - req := httptest.NewRequest(http.MethodPost, "/api/file", buf) - req.Header.Add("Content-Type", mw.FormDataContentType()) + req := httptest.NewRequest(http.MethodPost, "/api/file", buf) + req.Header.Add("Content-Type", mw.FormDataContentType()) - hs.Handler.ServeHTTP(rr, req) + hs.Handler.ServeHTTP(rr, req) - if status := rr.Code; status != http.StatusAccepted { - t.Errorf("Returned unexpected status. Got %d want %d", status, http.StatusAccepted) - } + if status := rr.Code; status != http.StatusAccepted { + t.Errorf("Returned unexpected status. Got %d want %d", status, http.StatusAccepted) + } - var expectedResp []struct { - Message string `json:"message"` - ID string `json:"id"` - URL string `json:"url"` - } + var expectedResp []struct { + Message string `json:"message"` + ID string `json:"id"` + URL string `json:"url"` + } - decoder := json.NewDecoder(rr.Result().Body) - if err := decoder.Decode(&expectedResp); err != nil { - t.Fatalf("error decoding response: %s", err) - } + decoder := json.NewDecoder(rr.Result().Body) + if err := decoder.Decode(&expectedResp); err != nil { + t.Fatalf("error decoding response: %s", err) + } - if l := len(expectedResp); l != 1 { - t.Errorf("Response has wrong length. Got %d want %d", l, 1) - } + if l := len(expectedResp); l != 1 { + t.Errorf("Response has wrong length. Got %d want %d", l, 1) + } - uploadID := expectedResp[0].ID - if uploadID == "" { - t.Errorf("Response has empty id") - } + uploadID := expectedResp[0].ID + if uploadID == "" { + t.Errorf("Response has empty id") + } - t.Run("HandlerAPIFileGet", func(t *testing.T) { - rr := httptest.NewRecorder() - url := fmt.Sprintf("/api/file/%s", uploadID) - req := httptest.NewRequest(http.MethodGet, url, nil) + retrieved, err := hs.Files.Get(uploadID) + if err != nil { + t.Errorf("Error retrieving file: %s", err) + } + defer retrieved.Body.Close() + retBuf := new(bytes.Buffer) + io.Copy(retBuf, retrieved.Body) + if diff := cmp.Diff(retBuf.String(), expectedData); diff != "" { + t.Errorf("Retrieved file mismatch: %s", diff) + } + }) + // GET /api/file/id + t.Run("GET", func(t *testing.T) { + hs := newServer() + fileData := "abc123456" + sr := io.NopCloser(strings.NewReader(fileData)) + file := &files.File{ + ID: uuid.NewString(), + OriginalFilename: "test-file.txt", + MaxViews: 99, + ExpiresOn: time.Now().Add(90 * time.Second), + Body: sr, + } + hs.Files.Store(file) + rr := httptest.NewRecorder() + url := fmt.Sprintf("/api/file/%s", file.ID) + req := httptest.NewRequest(http.MethodGet, url, nil) - hs.Handler.ServeHTTP(rr, req) + hs.Handler.ServeHTTP(rr, req) - if status := rr.Code; status != http.StatusOK { - t.Errorf("Returned unexpected status. Got %d want %d", status, http.StatusAccepted) - t.Logf(url) - } - if body := rr.Body.String(); body != expectedData { - t.Errorf("Returned body does not match expected.") - } + if status := rr.Code; status != http.StatusOK { + t.Errorf("Returned unexpected status. Got %d want %d", status, http.StatusAccepted) + t.Logf(url) + } + if diff := cmp.Diff(rr.Body.String(), fileData); diff != "" { + t.Errorf("Returned body does not match expected: %s", diff) + } + }) + + // DELETE /api/file/id + t.Run("DELETE", func(t *testing.T) { + hs := newServer() + fileBody := io.NopCloser(strings.NewReader("roflcopter")) + file := &files.File{ + ID: uuid.NewString(), + OriginalFilename: "testpls.txt", + MaxViews: 9, + ExpiresOn: time.Now().Add(10 * time.Hour), + Body: fileBody, + } + + if err := hs.Files.Store(file); err != nil { + t.Fatalf("Error storing file: %s", err) + } + + rr := httptest.NewRecorder() + url := fmt.Sprintf("/api/file/%s", file.ID) + req := httptest.NewRequest(http.MethodDelete, url, nil) + hs.Handler.ServeHTTP(rr, req) + + if rr.Result().StatusCode != http.StatusOK { + t.Fatalf("Delete returned wrong status: %s", rr.Result().Status) + } + + if _, err := hs.Files.Get(file.ID); err == nil { + t.Errorf("Getting after delete returned no error") + } + }) }) - }) - t.Run("HandlerAPIFileDelete", func(t *testing.T) { - cfg := &gpaste.ServerConfig{ - SigningSecret: "abc123", - Store: &gpaste.ServerStoreConfig{ - Type: "memory", - }, - URL: "http://localhost:8080", - } - hs := api.NewHTTPServer(cfg) - fileBody := io.NopCloser(strings.NewReader("roflcopter")) - file := &files.File{ - ID: uuid.NewString(), - OriginalFilename: "testpls.txt", - MaxViews: 9, - ExpiresOn: time.Now().Add(10 * time.Hour), - Body: fileBody, - } + // /api/user - if err := hs.Files.Store(file); err != nil { - t.Fatalf("Error storing file: %s", err) - } + t.Run("user", func(t *testing.T) { + t.Run("POST", func(t *testing.T) { + hs := newServer() + adminPw := "admin" + admin := &users.User{ + Username: "admin", + Role: users.RoleAdmin, + } + _ = admin.SetPassword(adminPw) + _ = hs.Users.Store(admin) - rr := httptest.NewRecorder() - url := fmt.Sprintf("/api/file/%s", file.ID) - req := httptest.NewRequest(http.MethodDelete, url, nil) - hs.Handler.ServeHTTP(rr, req) + token, err := hs.Auth.Login(admin.Username, adminPw) + if err != nil { + t.Fatalf("error getting admin token: %s", err) + } - if rr.Result().StatusCode != http.StatusOK { - t.Fatalf("Delete returned wrong status: %s", rr.Result().Status) - } + requestData := &api.RequestAPIUserCreate{ + Username: "test", + Password: "test", + } + body := new(bytes.Buffer) + encoder := json.NewEncoder(body) + if err := encoder.Encode(requestData); err != nil { + t.Fatalf("Error encoding data: %s", err) + } - if _, err := hs.Files.Get(file.ID); err == nil { - t.Errorf("Getting after delete returned no error") - } + rr := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodPost, "/api/user", body) + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) + hs.Handler.ServeHTTP(rr, req) - }) - t.Run("HandlerAPILogin", func(t *testing.T) { - // TODO: Add test - username := "admin" - password := "admin" - user := &users.User{Username: username} - if err := user.SetPassword(password); err != nil { - t.Fatalf("Error setting user password: %s", err) - } - if err := hs.Users.Store(user); err != nil { - t.Fatalf("Error storing user: %s", err) - } + if rr.Result().StatusCode != http.StatusAccepted { + t.Fatalf("Create returned wrong status: %s", rr.Result().Status) + } - requestData := struct { - Username string `json:"username"` - Password string `json:"password"` - }{ - Username: username, - Password: password, - } + user, err := hs.Users.Get(requestData.Username) + if err != nil { + t.Fatalf("Unable to get user after create: %s", err) + } - body := new(bytes.Buffer) - encoder := json.NewEncoder(body) - if err := encoder.Encode(&requestData); err != nil { - t.Fatalf("Error encoding request body: %s", err) - } + expectedUser := &users.User{ + Username: requestData.Username, + Role: users.RoleUser, + } + ignorePW := cmp.FilterPath(func(p cmp.Path) bool { + return p.String() == "HashedPassword" + }, cmp.Ignore()) - rr := httptest.NewRecorder() - req := httptest.NewRequest(http.MethodPost, "/api/login", body) + if diff := cmp.Diff(user, expectedUser, ignorePW); diff != "" { + t.Errorf("User does not match expected: %s", diff) + } + }) + }) - hs.Handler.ServeHTTP(rr, req) - - responseData := struct { - Token string `json:"token"` - }{} - - decoder := json.NewDecoder(rr.Body) - if err := decoder.Decode(&responseData); err != nil { - t.Fatalf("Error decoding response: %s", err) - } - - if _, err := hs.Auth.ValidateToken(responseData.Token); err != nil { - t.Fatalf("Unable to validate received token: %s", err) - } - }) - t.Run("User", func(t *testing.T) { - t.Run("Create", func(t *testing.T) { + // /api/login + t.Run("Login", func(t *testing.T) { hs := newServer() - adminPw := "admin" - admin := &users.User{ - Username: "admin", - Role: users.RoleAdmin, + // TODO: Add test + username := "admin" + password := "admin" + user := &users.User{Username: username} + if err := user.SetPassword(password); err != nil { + t.Fatalf("Error setting user password: %s", err) } - _ = admin.SetPassword(adminPw) - _ = hs.Users.Store(admin) - - token, err := hs.Auth.Login(admin.Username, adminPw) - if err != nil { - t.Fatalf("error getting admin token: %s", err) + if err := hs.Users.Store(user); err != nil { + t.Fatalf("Error storing user: %s", err) } - requestData := &api.RequestAPIUserCreate{ - Username: "test", - Password: "test", + requestData := struct { + Username string `json:"username"` + Password string `json:"password"` + }{ + Username: username, + Password: password, } + body := new(bytes.Buffer) encoder := json.NewEncoder(body) - if err := encoder.Encode(requestData); err != nil { - t.Fatalf("Error encoding data: %s", err) + if err := encoder.Encode(&requestData); err != nil { + t.Fatalf("Error encoding request body: %s", err) } rr := httptest.NewRecorder() - req := httptest.NewRequest(http.MethodPost, "/api/user", body) - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) + req := httptest.NewRequest(http.MethodPost, "/api/login", body) + hs.Handler.ServeHTTP(rr, req) - if rr.Result().StatusCode != http.StatusAccepted { - t.Fatalf("Create returned wrong status: %s", rr.Result().Status) + responseData := struct { + Token string `json:"token"` + }{} + + decoder := json.NewDecoder(rr.Body) + if err := decoder.Decode(&responseData); err != nil { + t.Fatalf("Error decoding response: %s", err) } - user, err := hs.Users.Get(requestData.Username) - if err != nil { - t.Fatalf("Unable to get user after create: %s", err) - } - - expectedUser := &users.User{ - Username: requestData.Username, - Role: users.RoleUser, - } - ignorePW := cmp.FilterPath(func(p cmp.Path) bool { - return p.String() == "HashedPassword" - }, cmp.Ignore()) - - if diff := cmp.Diff(user, expectedUser, ignorePW); diff != "" { - t.Errorf("User does not match expected: %s", diff) + if _, err := hs.Auth.ValidateToken(responseData.Token); err != nil { + t.Fatalf("Unable to validate received token: %s", err) } }) }) + } func newServer() *api.HTTPServer {