diff --git a/internal/api/api_integration_test.go b/internal/api/api_integration_test.go index c9838b66..890a19ab 100644 --- a/internal/api/api_integration_test.go +++ b/internal/api/api_integration_test.go @@ -2381,7 +2381,6 @@ func TestGetGlobalEntriesEndpoint(t *testing.T) { } feedIDEntry, err := regularUserClient.Feed(feedID) - if err != nil { t.Fatal(err) } @@ -2413,6 +2412,64 @@ func TestGetGlobalEntriesEndpoint(t *testing.T) { } } +func TestCannotGetRemovedEntries(t *testing.T) { + testConfig := newIntegrationTestConfig() + if !testConfig.isConfigured() { + t.Skip(skipIntegrationTestsMessage) + } + + adminClient := miniflux.NewClient(testConfig.testBaseURL, testConfig.testAdminUsername, testConfig.testAdminPassword) + + regularTestUser, err := adminClient.CreateUser(testConfig.genRandomUsername(), testConfig.testRegularPassword, false) + if err != nil { + t.Fatal(err) + } + defer adminClient.DeleteUser(regularTestUser.ID) + + regularUserClient := miniflux.NewClient(testConfig.testBaseURL, regularTestUser.Username, testConfig.testRegularPassword) + + feedID, err := regularUserClient.CreateFeed(&miniflux.FeedCreationRequest{ + FeedURL: testConfig.testFeedURL, + }) + if err != nil { + t.Fatal(err) + } + + feedEntries, err := regularUserClient.Entries(&miniflux.Filter{FeedID: feedID}) + if err != nil { + t.Fatal(err) + } + + if feedEntries.Total == 0 { + t.Fatalf(`Expected at least one entry, got none`) + } + + if err := regularUserClient.UpdateEntries([]int64{feedEntries.Entries[0].ID}, miniflux.EntryStatusRemoved); err != nil { + t.Fatal(err) + } + + if _, err := regularUserClient.Entry(feedEntries.Entries[0].ID); err != miniflux.ErrNotFound { + t.Fatalf(`Expected entry to be not found, got %v`, err) + } + + if _, err := regularUserClient.FeedEntry(feedID, feedEntries.Entries[0].ID); err != miniflux.ErrNotFound { + t.Fatalf(`Expected entry to be not found, got %v`, err) + } + + if _, err := regularUserClient.CategoryEntry(feedEntries.Entries[0].Feed.Category.ID, feedEntries.Entries[0].ID); err != miniflux.ErrNotFound { + t.Fatalf(`Expected entry to be not found, got %v`, err) + } + + updatedFeedEntries, err := regularUserClient.Entries(&miniflux.Filter{FeedID: feedID}) + if err != nil { + t.Fatal(err) + } + + if updatedFeedEntries.Total != feedEntries.Total-1 { + t.Fatalf(`Expected %d entries, got %d`, feedEntries.Total-1, updatedFeedEntries.Total) + } +} + func TestUpdateEnclosureEndpoint(t *testing.T) { testConfig := newIntegrationTestConfig() if !testConfig.isConfigured() { @@ -2631,64 +2688,6 @@ func TestUpdateEntryStatusEndpoint(t *testing.T) { } } -func TestUpdateEntryRemovedStatusEndpoint(t *testing.T) { - testConfig := newIntegrationTestConfig() - if !testConfig.isConfigured() { - t.Skip(skipIntegrationTestsMessage) - } - - adminClient := miniflux.NewClient(testConfig.testBaseURL, testConfig.testAdminUsername, testConfig.testAdminPassword) - - regularTestUser, err := adminClient.CreateUser(testConfig.genRandomUsername(), testConfig.testRegularPassword, false) - if err != nil { - t.Fatal(err) - } - defer adminClient.DeleteUser(regularTestUser.ID) - - regularUserClient := miniflux.NewClient(testConfig.testBaseURL, regularTestUser.Username, testConfig.testRegularPassword) - - feedID, err := regularUserClient.CreateFeed(&miniflux.FeedCreationRequest{ - FeedURL: testConfig.testFeedURL, - }) - if err != nil { - t.Fatal(err) - } - - result, err := regularUserClient.FeedEntries(feedID, nil) - if err != nil { - t.Fatalf(`Failed to get entries: %v`, err) - } - - // First we set the entry as "removed" - if err := regularUserClient.UpdateEntries([]int64{result.Entries[0].ID}, miniflux.EntryStatusRemoved); err != nil { - t.Fatal(err) - } - - entry, err := regularUserClient.Entry(result.Entries[0].ID) - if err != nil { - t.Fatal(err) - } - - if entry.Status != miniflux.EntryStatusRemoved { - t.Fatalf(`Invalid status, got %q instead of %q`, entry.Status, miniflux.EntryStatusRemoved) - } - - // Then we try to set it to "unread" - if err := regularUserClient.UpdateEntries([]int64{result.Entries[0].ID}, miniflux.EntryStatusUnread); err != nil { - t.Fatal(err) - } - - entry, err = regularUserClient.Entry(result.Entries[0].ID) - if err != nil { - t.Fatal(err) - } - - // It should stay set to "removed" - if entry.Status != miniflux.EntryStatusRemoved { - t.Fatalf(`Modified immutable status: got %q instead of %q`, entry.Status, miniflux.EntryStatusRemoved) - } -} - func TestUpdateEntryEndpoint(t *testing.T) { testConfig := newIntegrationTestConfig() if !testConfig.isConfigured() { @@ -2932,13 +2931,4 @@ func TestFlushHistoryEndpoint(t *testing.T) { if readEntries.Total != 0 { t.Fatalf(`Invalid total, got %d`, readEntries.Total) } - - removedEntries, err := regularUserClient.Entries(&miniflux.Filter{Status: miniflux.EntryStatusRemoved}) - if err != nil { - t.Fatal(err) - } - - if removedEntries.Total != 2 { - t.Fatalf(`Invalid total, got %d`, removedEntries.Total) - } } diff --git a/internal/api/entry.go b/internal/api/entry.go index 5b988d42..c59fae18 100644 --- a/internal/api/entry.go +++ b/internal/api/entry.go @@ -47,6 +47,7 @@ func (h *handler) getFeedEntry(w http.ResponseWriter, r *http.Request) { builder := h.store.NewEntryQueryBuilder(request.UserID(r)) builder.WithFeedID(feedID) builder.WithEntryID(entryID) + builder.WithoutStatus(model.EntryStatusRemoved) h.getEntryFromBuilder(w, r, builder) } @@ -58,6 +59,7 @@ func (h *handler) getCategoryEntry(w http.ResponseWriter, r *http.Request) { builder := h.store.NewEntryQueryBuilder(request.UserID(r)) builder.WithCategoryID(categoryID) builder.WithEntryID(entryID) + builder.WithoutStatus(model.EntryStatusRemoved) h.getEntryFromBuilder(w, r, builder) } @@ -66,6 +68,7 @@ func (h *handler) getEntry(w http.ResponseWriter, r *http.Request) { entryID := request.RouteInt64Param(r, "entryID") builder := h.store.NewEntryQueryBuilder(request.UserID(r)) builder.WithEntryID(entryID) + builder.WithoutStatus(model.EntryStatusRemoved) h.getEntryFromBuilder(w, r, builder) } @@ -136,6 +139,7 @@ func (h *handler) findEntries(w http.ResponseWriter, r *http.Request, feedID int builder.WithLimit(limit) builder.WithTags(tags) builder.WithEnclosures() + builder.WithoutStatus(model.EntryStatusRemoved) if request.HasQueryParam(r, "globally_visible") { globallyVisible := request.QueryBoolParam(r, "globally_visible", true)