diff --git a/src/cmd/server/handler/handler.go b/src/cmd/server/handler/handler.go new file mode 100644 index 0000000..41018b8 --- /dev/null +++ b/src/cmd/server/handler/handler.go @@ -0,0 +1,30 @@ +package handler + +import ( + "context" + "net/http" +) + +type Handler struct { + ctx context.Context +} + +func New(ctx context.Context) Handler { + return Handler{ctx: ctx} +} + +func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if err := h.serveHTTP(w, r); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + +func (h Handler) serveHTTP(w http.ResponseWriter, r *http.Request) error { + switch r.URL.Path { + case "/v1/vpntor": + return h.vpntor(r.Context(), r.Body) + default: + http.NotFound(w, r) + } + return nil +} diff --git a/src/cmd/server/handler/handler_test.go b/src/cmd/server/handler/handler_test.go new file mode 100644 index 0000000..6719a17 --- /dev/null +++ b/src/cmd/server/handler/handler_test.go @@ -0,0 +1,21 @@ +package handler_test + +import ( + "context" + "net/http" + "net/http/httptest" + "show-rss/src/cmd/server/handler" + "show-rss/src/db" + "testing" +) + +func TestHandler(t *testing.T) { + h := handler.New(db.Test(t, context.Background())) + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodGet, "/not-found", nil) + h.ServeHTTP(w, r) + if w.Code != http.StatusNotFound { + t.Errorf("%+v", w) + } +} diff --git a/src/cmd/server/handler.go b/src/cmd/server/handler/vpntor.go similarity index 72% rename from src/cmd/server/handler.go rename to src/cmd/server/handler/vpntor.go index dc5e7a2..c8aa6a5 100644 --- a/src/cmd/server/handler.go +++ b/src/cmd/server/handler/vpntor.go @@ -1,4 +1,4 @@ -package server +package handler import ( "bytes" @@ -11,30 +11,6 @@ import ( "time" ) -type Handler struct { - ctx context.Context -} - -func NewHandler(ctx context.Context) Handler { - return Handler{ctx: ctx} -} - -func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if err := h.serveHTTP(w, r); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } -} - -func (h Handler) serveHTTP(w http.ResponseWriter, r *http.Request) error { - switch r.URL.Path { - case "/v1/vpntor": - return h.vpntor(r.Context(), r.Body) - default: - http.NotFound(w, r) - } - return nil -} - func (h Handler) vpntor(ctx context.Context, r io.Reader) error { var form struct { Magnet string diff --git a/src/cmd/server/handler/vpntor_test.go b/src/cmd/server/handler/vpntor_test.go new file mode 100644 index 0000000..14c0c5b --- /dev/null +++ b/src/cmd/server/handler/vpntor_test.go @@ -0,0 +1,66 @@ +package handler_test + +import ( + "context" + "fmt" + "io" + "net/http" + "net/http/httptest" + "show-rss/src/cmd/server/handler" + "show-rss/src/db" + "strings" + "testing" +) + +func TestVpntor(t *testing.T) { + h := handler.New(db.Test(t, context.Background())) + + t.Run("no body", func(t *testing.T) { + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodGet, "/v1/vpntor", nil) + h.ServeHTTP(w, r) + if w.Code != http.StatusInternalServerError { + t.Errorf("%+v", w) + } + }) + + t.Run("bad body", func(t *testing.T) { + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPost, "/v1/vpntor", strings.NewReader(`{}`)) + h.ServeHTTP(w, r) + t.Logf("%s", w.Body.Bytes()) + if w.Code != http.StatusInternalServerError { + t.Errorf("%+v", w.Code) + } + if !strings.Contains(string(w.Body.Bytes()), `.Magnet, .Dir, .URL`) { + t.Errorf("%+v", string(w.Body.Bytes())) + } + }) + + t.Run("doit", func(t *testing.T) { + calls := 0 + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + b, _ := io.ReadAll(r.Body) + t.Logf("%s | %s", r.Header.Get("X-Transmission-Session-Id"), b) + calls += 1 + w.Header().Set("X-Transmission-Session-Id", "session") + w.Write([]byte(`success`)) + })) + defer s.Close() + + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPost, "/v1/vpntor", strings.NewReader(fmt.Sprintf(`{ + "Magnet": %q, + "Dir": %q, + "URL": %q + }`, "magnet", "dir", s.URL))) + h.ServeHTTP(w, r) + if w.Code != http.StatusOK { + t.Errorf("%+v", w.Code) + } + + if calls != 2 { + t.Errorf("expected 2 but got %d calls", calls) + } + }) +} diff --git a/src/cmd/server/handler_test.go b/src/cmd/server/handler_test.go deleted file mode 100644 index 434a672..0000000 --- a/src/cmd/server/handler_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package server_test - -import ( - "context" - "fmt" - "io" - "net/http" - "net/http/httptest" - "show-rss/src/cmd/server" - "show-rss/src/db" - "strings" - "testing" -) - -func TestHandler(t *testing.T) { - h := server.NewHandler(db.Test(t, context.Background())) - - t.Run("404", func(t *testing.T) { - w := httptest.NewRecorder() - r := httptest.NewRequest(http.MethodGet, "/not-found", nil) - h.ServeHTTP(w, r) - if w.Code != http.StatusNotFound { - t.Errorf("%+v", w) - } - }) - - t.Run("vpntor", func(t *testing.T) { - t.Run("no body", func(t *testing.T) { - w := httptest.NewRecorder() - r := httptest.NewRequest(http.MethodGet, "/v1/vpntor", nil) - h.ServeHTTP(w, r) - if w.Code != http.StatusInternalServerError { - t.Errorf("%+v", w) - } - }) - - t.Run("bad body", func(t *testing.T) { - w := httptest.NewRecorder() - r := httptest.NewRequest(http.MethodPost, "/v1/vpntor", strings.NewReader(`{}`)) - h.ServeHTTP(w, r) - t.Logf("%s", w.Body.Bytes()) - if w.Code != http.StatusInternalServerError { - t.Errorf("%+v", w.Code) - } - if !strings.Contains(string(w.Body.Bytes()), `.Magnet, .Dir, .URL`) { - t.Errorf("%+v", string(w.Body.Bytes())) - } - }) - - t.Run("doit", func(t *testing.T) { - calls := 0 - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - b, _ := io.ReadAll(r.Body) - t.Logf("%s | %s", r.Header.Get("X-Transmission-Session-Id"), b) - calls += 1 - w.Header().Set("X-Transmission-Session-Id", "session") - w.Write([]byte(`success`)) - })) - defer s.Close() - - w := httptest.NewRecorder() - r := httptest.NewRequest(http.MethodPost, "/v1/vpntor", strings.NewReader(fmt.Sprintf(`{ - "Magnet": %q, - "Dir": %q, - "URL": %q - }`, "magnet", "dir", s.URL))) - h.ServeHTTP(w, r) - if w.Code != http.StatusOK { - t.Errorf("%+v", w.Code) - } - - if calls != 2 { - t.Errorf("expected 2 but got %d calls", calls) - } - }) - }) -} diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go index bb295e8..a7aa6d2 100644 --- a/src/cmd/server/main.go +++ b/src/cmd/server/main.go @@ -6,6 +6,7 @@ import ( "net" "net/http" "os" + "show-rss/src/cmd/server/handler" "strconv" ) @@ -24,7 +25,7 @@ func Run(ctx context.Context, listen string) error { s := http.Server{ Addr: listen, - Handler: NewHandler(ctx), + Handler: handler.New(ctx), BaseContext: func(net.Listener) context.Context { return ctx }, } defer s.Close()