diff options
| author | Philipp Tanlak <philipp.tanlak@gmail.com> | 2023-08-11 18:31:20 +0200 |
|---|---|---|
| committer | Philipp Tanlak <philipp.tanlak@gmail.com> | 2023-08-11 18:31:20 +0200 |
| commit | 062b36fe5725d1267c66db2e506b4131d78ce772 (patch) | |
| tree | 998e5260feb1babac8dae512b56d67d8f20f7266 /api | |
| parent | 7e4cf39a0ba6ccbd5cc036700a8b1ff9358ecc3d (diff) | |
simplify project structure
Diffstat (limited to 'api')
| -rw-r--r-- | api/api.go | 84 | ||||
| -rw-r--r-- | api/api_service_mock_test.go | 80 | ||||
| -rw-r--r-- | api/api_test.go | 67 |
3 files changed, 0 insertions, 231 deletions
diff --git a/api/api.go b/api/api.go deleted file mode 100644 index 893dd00..0000000 --- a/api/api.go +++ /dev/null @@ -1,84 +0,0 @@ -package api - -import ( - "encoding/json" - "net/http" - - "github.com/alexedwards/flow" -) - -type ScrapeRequest struct { - URL string `json:"url"` - Data map[string]any `json:"data"` -} - -type ScrapeResponse struct { - URL string `json:"url"` - Data any `json:"data"` -} - -//go:generate moq -out api_service_mock_test.go . Service -type Service interface { - ScrapeURL(url string, params map[string]any) (any, error) -} - -func NewHandler(svc Service) http.Handler { - h := &Handler{ - router: flow.New(), - svc: svc, - } - h.routes() - return h -} - -type Handler struct { - router *flow.Mux - svc Service -} - -func (h *Handler) routes() { - h.router.HandleFunc("/scrape", h.handleScrape, "POST") -} - -func (h *Handler) handleScrape(w http.ResponseWriter, r *http.Request) { - var req ScrapeRequest - if err := decodeRequest(r, &req); err != nil { - respondErr(w, http.StatusBadRequest, err) - return - } - - result, err := h.svc.ScrapeURL(req.URL, req.Data) - if err != nil { - respondErr(w, http.StatusInternalServerError, err) - return - } - - respond(w, ScrapeResponse{ - URL: req.URL, - Data: result, - }) -} - -func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - h.router.ServeHTTP(w, r) -} - -func decodeRequest(r *http.Request, v any) error { - return json.NewDecoder(r.Body).Decode(v) -} - -func respond(w http.ResponseWriter, v any) { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(v) -} - -func respondErr(w http.ResponseWriter, statusCode int, err error) { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(statusCode) - json.NewEncoder(w).Encode(struct { - Error string `json:"error"` - }{ - Error: err.Error(), - }) -} diff --git a/api/api_service_mock_test.go b/api/api_service_mock_test.go deleted file mode 100644 index a7536be..0000000 --- a/api/api_service_mock_test.go +++ /dev/null @@ -1,80 +0,0 @@ -// Code generated by moq; DO NOT EDIT. -// github.com/matryer/moq - -package api - -import ( - "sync" -) - -// Ensure, that ServiceMock does implement Service. -// If this is not the case, regenerate this file with moq. -var _ Service = &ServiceMock{} - -// ServiceMock is a mock implementation of Service. -// -// func TestSomethingThatUsesService(t *testing.T) { -// -// // make and configure a mocked Service -// mockedService := &ServiceMock{ -// ScrapeURLFunc: func(url string, params map[string]any) (any, error) { -// panic("mock out the ScrapeURL method") -// }, -// } -// -// // use mockedService in code that requires Service -// // and then make assertions. -// -// } -type ServiceMock struct { - // ScrapeURLFunc mocks the ScrapeURL method. - ScrapeURLFunc func(url string, params map[string]any) (any, error) - - // calls tracks calls to the methods. - calls struct { - // ScrapeURL holds details about calls to the ScrapeURL method. - ScrapeURL []struct { - // URL is the url argument value. - URL string - // Params is the params argument value. - Params map[string]any - } - } - lockScrapeURL sync.RWMutex -} - -// ScrapeURL calls ScrapeURLFunc. -func (mock *ServiceMock) ScrapeURL(url string, params map[string]any) (any, error) { - if mock.ScrapeURLFunc == nil { - panic("ServiceMock.ScrapeURLFunc: method is nil but Service.ScrapeURL was just called") - } - callInfo := struct { - URL string - Params map[string]any - }{ - URL: url, - Params: params, - } - mock.lockScrapeURL.Lock() - mock.calls.ScrapeURL = append(mock.calls.ScrapeURL, callInfo) - mock.lockScrapeURL.Unlock() - return mock.ScrapeURLFunc(url, params) -} - -// ScrapeURLCalls gets all the calls that were made to ScrapeURL. -// Check the length with: -// -// len(mockedService.ScrapeURLCalls()) -func (mock *ServiceMock) ScrapeURLCalls() []struct { - URL string - Params map[string]any -} { - var calls []struct { - URL string - Params map[string]any - } - mock.lockScrapeURL.RLock() - calls = mock.calls.ScrapeURL - mock.lockScrapeURL.RUnlock() - return calls -} diff --git a/api/api_test.go b/api/api_test.go deleted file mode 100644 index 624b684..0000000 --- a/api/api_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package api_test - -import ( - "encoding/json" - "errors" - "net/http" - "net/http/httptest" - "strings" - "testing" - - "flyscrape/api" - - "github.com/stretchr/testify/require" -) - -func TestScrapeURL(t *testing.T) { - svc := &api.ServiceMock{ - ScrapeURLFunc: func(url string, params map[string]any) (any, error) { - return map[string]any{"foo": "bar"}, nil - }, - } - h := api.NewHandler(svc) - - r := httptest.NewRequest("POST", "/scrape", strings.NewReader(`{"url": "https://example.com", "data": {"foo":".foo"}}`)) - w := httptest.NewRecorder() - h.ServeHTTP(w, r) - - require.Equal(t, w.Result().StatusCode, http.StatusOK) - require.Equal(t, w.Result().Header.Get("Content-Type"), "application/json") - - result := map[string]any{} - require.NoError(t, json.NewDecoder(w.Result().Body).Decode(&result)) - require.Equal(t, result["url"].(string), "https://example.com") - require.Equal(t, result["data"].(map[string]any)["foo"], "bar") -} - -func TestScrapeURLInternalServerError(t *testing.T) { - svc := &api.ServiceMock{ - ScrapeURLFunc: func(url string, params map[string]any) (any, error) { - return nil, errors.New("whoops") - }, - } - h := api.NewHandler(svc) - - r := httptest.NewRequest("POST", "/scrape", strings.NewReader(`{"url": "https://example.com", "data": {"foo":".foo"}}`)) - w := httptest.NewRecorder() - h.ServeHTTP(w, r) - - require.Equal(t, w.Result().StatusCode, http.StatusInternalServerError) - require.Equal(t, w.Result().Header.Get("Content-Type"), "application/json") -} - -func TestScrapeURLBadRequest(t *testing.T) { - svc := &api.ServiceMock{ - ScrapeURLFunc: func(url string, params map[string]any) (any, error) { - return nil, errors.New("whoops") - }, - } - h := api.NewHandler(svc) - - r := httptest.NewRequest("POST", "/scrape", strings.NewReader(`{"}`)) - w := httptest.NewRecorder() - h.ServeHTTP(w, r) - - require.Equal(t, w.Result().StatusCode, http.StatusBadRequest) - require.Equal(t, w.Result().Header.Get("Content-Type"), "application/json") -} |