package vanity import ( "context" "encoding/json" "net/http" "net/http/httptest" "os" "strings" "testing" ) var ( server *httptest.Server token = "TestingLibrary" version = "VanityTest" packages = []Package{ { Name: "test1", Description: "test1", Branch: "main", WebURL: "https://gitea.com/jolheiser/test1", CloneHTTP: "https://gitea.com/jolheiser/test1.git", CloneSSH: "https://gitea.com/jolheiser/test1", }, } ) func TestMain(m *testing.M) { server = httptest.NewServer(http.HandlerFunc(testServer)) os.Exit(m.Run()) } func TestClient(t *testing.T) { ctx := context.Background() client := New("", WithServer(server.URL)) // Info checkInfo(t, client, 1) pkg1 := Package{ Name: "test1", Description: "test1", Branch: "main", WebURL: "https://gitea.com/jolheiser/test1", CloneHTTP: "https://gitea.com/jolheiser/test1.git", CloneSSH: "https://gitea.com/jolheiser/test1", } pkg2 := Package{ Name: "test2", Description: "test2", Branch: "main", WebURL: "https://gitea.com/jolheiser/test2", CloneHTTP: "https://gitea.com/jolheiser/test2.git", CloneSSH: "https://gitea.com/jolheiser/test2", } // Add (without token) if err := client.Add(ctx, pkg1); err == nil { t.Log("adding without token should fail") t.Fail() } // Add (with token) client = New(token, WithServer(server.URL)) checkAdd(t, client, pkg1, pkg2) // Info (after second package) checkInfo(t, client, 2) // Update package checkUpdate(t, client, pkg1) // Remove checkRemove(t, client, pkg1) // Info (final) checkInfo(t, client, 1) } func checkInfo(t *testing.T, client *Client, numPackages int) { info, err := client.Info(context.Background()) if err != nil { t.Logf("info should not return error: %v\n", err) t.Fail() } if info.Version != version || info.NumPackages != numPackages { t.Log("info did not match expected") t.Fail() } } func checkAdd(t *testing.T, client *Client, pkg1, pkg2 Package) { ctx := context.Background() if err := client.Add(ctx, pkg2); err != nil { t.Logf("pkg2 should be added: %v\n", err) t.Fail() } // Duplicate package if err := client.Add(ctx, pkg1); err == nil { t.Log("pkg1 should already exist") t.Fail() } } func checkUpdate(t *testing.T, client *Client, pkg Package) { ctx := context.Background() // Update invalid package if err := client.Update(ctx, Package{Name: "test4"}); err == nil { t.Log("should not be able to update invalid package") t.Fail() } // Update valid package if err := client.Update(ctx, pkg); err != nil { t.Logf("should be able to update valid package: %v\n", err) t.Fail() } } func checkRemove(t *testing.T, client *Client, pkg Package) { ctx := context.Background() if err := client.Remove(ctx, pkg); err != nil { t.Logf("should be able to remove package: %v\n", err) t.Fail() } // Remove (idempotent) if err := client.Remove(ctx, pkg); err != nil { t.Logf("should be able to remove package idempotently: %v\n", err) t.Fail() } } func testServer(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/": switch r.Method { case http.MethodOptions: resp := Info{ Version: version, NumPackages: len(packages), } _ = json.NewEncoder(w).Encode(resp) case http.MethodPost, http.MethodPatch, http.MethodDelete: if r.Header.Get(TokenHeader) != token { w.WriteHeader(http.StatusUnauthorized) return } var pkg Package if err := json.NewDecoder(r.Body).Decode(&pkg); err != nil { w.WriteHeader(http.StatusInternalServerError) return } switch r.Method { case http.MethodPost: for _, p := range packages { if p.Name == pkg.Name { w.WriteHeader(http.StatusConflict) return } } packages = append(packages, pkg) w.WriteHeader(http.StatusCreated) case http.MethodPatch: for idx, p := range packages { if p.Name == pkg.Name { packages[idx] = pkg return } } w.WriteHeader(http.StatusNotFound) case http.MethodDelete: for idx, p := range packages { if p.Name == pkg.Name { packages = append(packages[:idx], packages[idx+1:]...) } } } return } return default: name := strings.TrimPrefix(r.URL.Path, "/") for _, pkg := range packages { if pkg.Name == name { _ = json.NewEncoder(w).Encode(pkg) return } } } w.WriteHeader(http.StatusNotImplemented) }