diff --git a/.drone.yml b/.drone.yml index 6cd48ef..d40a36b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -11,10 +11,7 @@ steps: - go vet ./... group: test-lint # escalated permissions to avoid runtime/cgo: pthread_create failed: Operation not permitted - # security: - # syscaps: - # - SYS_PTRACE - # - IPC_LOCK + # TODO investigate syscaps or privileged: true trigger: diff --git a/cmd/bugbox/main.go b/cmd/bugbox/main.go index 132579c..760856f 100644 --- a/cmd/bugbox/main.go +++ b/cmd/bugbox/main.go @@ -7,8 +7,15 @@ import ( "git.runcible.io/learning/bugbox" ) +type InMemoryEnclosureStore struct{} + +func (i *InMemoryEnclosureStore) GetEnclosure(name string) string { + return name +} + func main() { - log.Println("Serving on port: 8888") - handler := http.HandlerFunc(bugbox.BugBoxServer) - log.Fatal(http.ListenAndServe(":8888", handler)) + log.Println("Serving on: http://0.0.0.0:8888") + enclosureStore := InMemoryEnclosureStore{} + server := &bugbox.BugBoxServer{EnclosureStore: &enclosureStore} + log.Fatal(http.ListenAndServe(":8888", server)) } diff --git a/server.go b/server.go index 383f8eb..e9a640a 100644 --- a/server.go +++ b/server.go @@ -6,12 +6,28 @@ import ( "strings" ) -// GetEnclosure retrieves the requested enclosure -func GetEnclosure(name string) string { - return name +// EnclosureStore describes an interface to managing Enclosures +type EnclosureStore interface { + // Retrieves an enclosure by name + GetEnclosure(name string) string } -func BugBoxServer(w http.ResponseWriter, r *http.Request) { +type BugBoxServer struct { + EnclosureStore EnclosureStore +} + +// This implements the Handler interface +func (b *BugBoxServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { enclosure := strings.TrimPrefix(r.URL.Path, "/enclosure/") - fmt.Fprint(w, GetEnclosure(enclosure)) + e := b.EnclosureStore.GetEnclosure(enclosure) + if e == "" { + w.WriteHeader(http.StatusNotFound) + } + + fmt.Fprint(w, e) +} + +// GetEnclosure retrieves the requested enclosure +func GetEnclosure(name string) string { + return name } diff --git a/server_test.go b/server_test.go index ef88f9f..90efba1 100644 --- a/server_test.go +++ b/server_test.go @@ -20,16 +20,40 @@ func assertResponseBody(t testing.TB, got, want string) { } } +func assertStatus(t testing.TB, got, want int) { + t.Helper() + if got != want { + t.Errorf("Status error, got %d want %d", got, want) + } +} + +type MockEnclosureStore struct { + enclosures map[string]string +} + +func (s *MockEnclosureStore) GetEnclosure(name string) string { + e := s.enclosures[name] + return e +} + func TestGETEnclosures(t *testing.T) { + mockEnclosureStore := MockEnclosureStore{ + map[string]string{ + "1337": "1337", + "7331": "7331"}, + } + server := &BugBoxServer{EnclosureStore: &mockEnclosureStore} + t.Run("returns enclosure 1337", func(t *testing.T) { // nil is used since we are not providing a request body request := newGETEnclosureRequest("1337") // response is a ResponseRecorder used for spying on response response := httptest.NewRecorder() - BugBoxServer(response, request) + server.ServeHTTP(response, request) assertResponseBody(t, response.Body.String(), "1337") + assertStatus(t, response.Code, http.StatusOK) }) t.Run("returns enclosure 7331", func(t *testing.T) { @@ -38,8 +62,18 @@ func TestGETEnclosures(t *testing.T) { // response is a ResponseRecorder used for spying on response response := httptest.NewRecorder() - BugBoxServer(response, request) + server.ServeHTTP(response, request) assertResponseBody(t, response.Body.String(), "7331") + assertStatus(t, response.Code, http.StatusOK) + }) + + t.Run("returns 404 when enclosure missing", func(t *testing.T) { + request := newGETEnclosureRequest("9000") + response := httptest.NewRecorder() + + server.ServeHTTP(response, request) + + assertStatus(t, response.Code, http.StatusNotFound) }) }