From 2e4add8a1c258a8da55b20589ce60398102740ad Mon Sep 17 00:00:00 2001 From: stephen mcquay Date: Tue, 1 Mar 2016 23:34:31 -0800 Subject: [PATCH] Adds DELETE. Fixes #11 Change-Id: I3b4aadc85055f2d2f4efb9e2e95bde6924320f35 --- api_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ server.go | 12 +++++++++++- storage.go | 6 ++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/api_test.go b/api_test.go index 49f0da9..f553ca1 100644 --- a/api_test.go +++ b/api_test.go @@ -264,3 +264,52 @@ func TestNewServer(t *testing.T) { t.Errorf("should have failed to post at bad route; got %s, want %s", resp.Status, http.StatusText(want)) } } + +func TestDelete(t *testing.T) { + ms := NewSimpleStore("") + sm := http.NewServeMux() + _ = NewServer(sm, ms) + ts := httptest.NewServer(sm) + resp, err := http.Get(ts.URL) + if err != nil { + t.Errorf("couldn't GET: %v", err) + } + resp.Body.Close() + if len(ms.p) != 0 { + t.Errorf("started with something in it; got %d, want %d", len(ms.p), 0) + } + + u := fmt.Sprintf("%s/foo", ts.URL) + resp, err = http.Post(u, "application/json", strings.NewReader(`{"repo": "https://s.mcquay.me/sm/vain"}`)) + if err != nil { + t.Errorf("couldn't POST: %v", err) + } + + if got, want := len(ms.p), 1; got != want { + t.Errorf("storage should have something in it; got %d, want %d", got, want) + } + + { + // test not found + u := fmt.Sprintf("%s/bar", ts.URL) + client := &http.Client{} + req, err := http.NewRequest("DELETE", u, nil) + resp, err = client.Do(req) + if err != nil { + t.Errorf("couldn't POST: %v", err) + } + if got, want := resp.StatusCode, http.StatusNotFound; got != want { + t.Errorf("should have not been able to delete unknown package; got %v, want %v", http.StatusText(got), http.StatusText(want)) + } + } + client := &http.Client{} + req, err := http.NewRequest("DELETE", u, nil) + resp, err = client.Do(req) + if err != nil { + t.Errorf("couldn't POST: %v", err) + } + + if got, want := len(ms.p), 0; got != want { + t.Errorf("storage should be empty; got %d, want %d", got, want) + } +} diff --git a/server.go b/server.go index aec5257..bac0bc7 100644 --- a/server.go +++ b/server.go @@ -59,8 +59,18 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { http.Error(w, fmt.Sprintf("unable to add package: %v", err), http.StatusInternalServerError) return } + case "DELETE": + p := fmt.Sprintf("%s/%s", req.Host, strings.Trim(req.URL.Path, "/")) + if !s.storage.Contains(p) { + http.Error(w, fmt.Sprintf("package %q not found", p), http.StatusNotFound) + return + } + if err := s.storage.Remove(p); err != nil { + http.Error(w, fmt.Sprintf("unable to delete package: %v", err), http.StatusInternalServerError) + return + } default: - http.Error(w, fmt.Sprintf("unsupported method %q; accepted: POST, GET", req.Method), http.StatusMethodNotAllowed) + http.Error(w, fmt.Sprintf("unsupported method %q; accepted: POST, GET, DELETE", req.Method), http.StatusMethodNotAllowed) } } diff --git a/storage.go b/storage.go index be04a16..e1b0493 100644 --- a/storage.go +++ b/storage.go @@ -21,6 +21,7 @@ func Valid(p string, packages []Package) bool { // Storage is a shim to allow for alternate storage types. type Storage interface { + Contains(name string) bool Add(p Package) error Remove(path string) error All() []Package @@ -43,6 +44,11 @@ func NewSimpleStore(path string) *SimpleStore { } } +func (ms *SimpleStore) Contains(name string) bool { + _, contains := ms.p[name] + return contains +} + // Add adds p to the SimpleStore. func (ms *SimpleStore) Add(p Package) error { ms.l.Lock()