From eb4bca6eb796fd1032a46756b5de0aa16f5fbd82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Sun, 18 Aug 2024 12:07:57 -0700 Subject: [PATCH] fix: `store.GetEnclosure()` should return `nil` if no rows are returned --- client/client.go | 6 ++---- internal/api/api.go | 4 ++-- internal/api/api_integration_test.go | 18 +++++++++++------- internal/api/enclosure.go | 17 ++++++++--------- internal/storage/enclosure.go | 8 +++++--- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/client/client.go b/client/client.go index 71ced695..11659164 100644 --- a/client/client.go +++ b/client/client.go @@ -613,17 +613,15 @@ func (c *Client) Icon(iconID int64) (*FeedIcon, error) { return feedIcon, nil } +// Enclosure fetches a specific enclosure. func (c *Client) Enclosure(enclosureID int64) (*Enclosure, error) { body, err := c.request.Get(fmt.Sprintf("/v1/enclosures/%d", enclosureID)) - if err != nil { return nil, err } - defer body.Close() var enclosure *Enclosure - if err := json.NewDecoder(body).Decode(&enclosure); err != nil { return nil, fmt.Errorf("miniflux: response error(%v)", err) } @@ -631,9 +629,9 @@ func (c *Client) Enclosure(enclosureID int64) (*Enclosure, error) { return enclosure, nil } +// UpdateEnclosure updates an enclosure. func (c *Client) UpdateEnclosure(enclosureID int64, enclosureUpdate *EnclosureUpdateRequest) error { _, err := c.request.Put(fmt.Sprintf("/v1/enclosures/%d", enclosureID), enclosureUpdate) - return err } diff --git a/internal/api/api.go b/internal/api/api.go index 1109acda..48d13039 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -72,8 +72,8 @@ func Serve(router *mux.Router, store *storage.Storage, pool *worker.Pool) { sr.HandleFunc("/entries/{entryID}/fetch-content", handler.fetchContent).Methods(http.MethodGet) sr.HandleFunc("/flush-history", handler.flushHistory).Methods(http.MethodPut, http.MethodDelete) sr.HandleFunc("/icons/{iconID}", handler.getIconByIconID).Methods(http.MethodGet) - sr.HandleFunc("/enclosures/{enclosureID}", handler.getEnclosureById).Methods(http.MethodGet) - sr.HandleFunc("/enclosures/{enclosureID}", handler.updateEnclosureById).Methods(http.MethodPut) + sr.HandleFunc("/enclosures/{enclosureID}", handler.getEnclosureByID).Methods(http.MethodGet) + sr.HandleFunc("/enclosures/{enclosureID}", handler.updateEnclosureByID).Methods(http.MethodPut) sr.HandleFunc("/version", handler.versionHandler).Methods(http.MethodGet) } diff --git a/internal/api/api_integration_test.go b/internal/api/api_integration_test.go index 3fd98119..1d06fb8c 100644 --- a/internal/api/api_integration_test.go +++ b/internal/api/api_integration_test.go @@ -67,10 +67,14 @@ func TestIncorrectEndpoint(t *testing.T) { } client := miniflux.NewClient("incorrect url") - _, err := client.Users() - if err == nil { + if _, err := client.Users(); err == nil { t.Fatal(`Using an incorrect URL should raise an error`) } + + client = miniflux.NewClient("") + if _, err := client.Users(); err == nil { + t.Fatal(`Using an empty URL should raise an error`) + } } func TestHealthcheckEndpoint(t *testing.T) { @@ -2074,7 +2078,6 @@ func TestUpdateEnclosureEndpoint(t *testing.T) { } var enclosure *miniflux.Enclosure - for _, entry := range result.Entries { if len(entry.Enclosures) > 0 { enclosure = entry.Enclosures[0] @@ -2089,13 +2092,11 @@ func TestUpdateEnclosureEndpoint(t *testing.T) { err = regularUserClient.UpdateEnclosure(enclosure.ID, &miniflux.EnclosureUpdateRequest{ MediaProgression: 20, }) - if err != nil { t.Fatal(err) } updatedEnclosure, err := regularUserClient.Enclosure(enclosure.ID) - if err != nil { t.Fatal(err) } @@ -2134,7 +2135,6 @@ func TestGetEnclosureEndpoint(t *testing.T) { } var expectedEnclosure *miniflux.Enclosure - for _, entry := range result.Entries { if len(entry.Enclosures) > 0 { expectedEnclosure = entry.Enclosures[0] @@ -2147,7 +2147,6 @@ func TestGetEnclosureEndpoint(t *testing.T) { } enclosure, err := regularUserClient.Enclosure(expectedEnclosure.ID) - if err != nil { t.Fatal(err) } @@ -2155,7 +2154,12 @@ func TestGetEnclosureEndpoint(t *testing.T) { if enclosure.ID != expectedEnclosure.ID { t.Fatalf(`Invalid enclosureID, got %d while expecting %d`, enclosure.ID, expectedEnclosure.ID) } + + if _, err = regularUserClient.Enclosure(99999); err == nil { + t.Fatalf(`Fetching an inexisting enclosure should raise an error`) + } } + func TestGetEntryEndpoints(t *testing.T) { testConfig := newIntegrationTestConfig() if !testConfig.isConfigured() { diff --git a/internal/api/enclosure.go b/internal/api/enclosure.go index 45222b33..2fc176be 100644 --- a/internal/api/enclosure.go +++ b/internal/api/enclosure.go @@ -13,18 +13,21 @@ import ( "miniflux.app/v2/internal/validator" ) -func (h *handler) getEnclosureById(w http.ResponseWriter, r *http.Request) { +func (h *handler) getEnclosureByID(w http.ResponseWriter, r *http.Request) { enclosureID := request.RouteInt64Param(r, "enclosureID") enclosure, err := h.store.GetEnclosure(enclosureID) - if err != nil { + json.ServerError(w, r, err) + return + } + + if enclosure == nil { json.NotFound(w, r) return } userID := request.UserID(r) - if enclosure.UserID != userID { json.NotFound(w, r) return @@ -35,11 +38,10 @@ func (h *handler) getEnclosureById(w http.ResponseWriter, r *http.Request) { json.OK(w, r, enclosure) } -func (h *handler) updateEnclosureById(w http.ResponseWriter, r *http.Request) { +func (h *handler) updateEnclosureByID(w http.ResponseWriter, r *http.Request) { enclosureID := request.RouteInt64Param(r, "enclosureID") var enclosureUpdateRequest model.EnclosureUpdateRequest - if err := json_parser.NewDecoder(r.Body).Decode(&enclosureUpdateRequest); err != nil { json.BadRequest(w, r, err) return @@ -51,9 +53,8 @@ func (h *handler) updateEnclosureById(w http.ResponseWriter, r *http.Request) { } enclosure, err := h.store.GetEnclosure(enclosureID) - if err != nil { - json.BadRequest(w, r, err) + json.ServerError(w, r, err) return } @@ -63,14 +64,12 @@ func (h *handler) updateEnclosureById(w http.ResponseWriter, r *http.Request) { } userID := request.UserID(r) - if enclosure.UserID != userID { json.NotFound(w, r) return } enclosure.MediaProgression = enclosureUpdateRequest.MediaProgression - if err := h.store.UpdateEnclosure(enclosure); err != nil { json.ServerError(w, r, err) return diff --git a/internal/storage/enclosure.go b/internal/storage/enclosure.go index 1f3a832b..e212795f 100644 --- a/internal/storage/enclosure.go +++ b/internal/storage/enclosure.go @@ -90,7 +90,9 @@ func (s *Storage) GetEnclosure(enclosureID int64) (*model.Enclosure, error) { &enclosure.MediaProgression, ) - if err != nil { + if err == sql.ErrNoRows { + return nil, nil + } else if err != nil { return nil, fmt.Errorf(`store: unable to fetch enclosure row: %v`, err) } @@ -164,8 +166,8 @@ func (s *Storage) UpdateEnclosure(enclosure *model.Enclosure) error { url=$1, size=$2, mime_type=$3, - entry_id=$4, - user_id=$5, + entry_id=$4, + user_id=$5, media_progression=$6 WHERE id=$7