diff --git a/internal/cli/agent.go b/internal/cli/agent.go index 6cfd0ce..1fa6b3d 100644 --- a/internal/cli/agent.go +++ b/internal/cli/agent.go @@ -187,7 +187,7 @@ func SearchCmd(d Deps, account, folder string, sc mail.SearchCriteria, limit int return d.emit(*fail) } defer done() - headers, err := m.Search(folder, sc, limit) + headers, err := m.Search(folder, sc, 0) if err != nil { return d.emit(Failure(CodeNetwork, err.Error())) } diff --git a/internal/cli/agent_test.go b/internal/cli/agent_test.go index 28a9996..2d9918a 100644 --- a/internal/cli/agent_test.go +++ b/internal/cli/agent_test.go @@ -152,6 +152,38 @@ func TestGetFilteredReturnsErrorForExit(t *testing.T) { } } +func TestSearchLimitCountsVisibleOnly(t *testing.T) { + // fakeMailer.Search returns all headers regardless of the limit passed in. + // Headers: UIDs 1,3,5 are visible (@trusted.com); UIDs 2,4 are filtered. + // With limit=2, SearchCmd must return 2 visible messages — not fewer, which + // would happen if the mail layer truncated to limit=2 before filtering. + fm := &fakeMailer{ + uidValidity: 1, maxUID: 5, + headers: []mail.Header{ + {UID: 1, From: "a@trusted.com", Subject: "one"}, + {UID: 2, From: "x@evil.com", Subject: "spam1"}, // filtered + {UID: 3, From: "b@trusted.com", Subject: "two"}, + {UID: 4, From: "y@evil.com", Subject: "spam2"}, // filtered + {UID: 5, From: "c@trusted.com", Subject: "three"}, + }, + } + d, buf := newDeps(t, fm) + if err := SearchCmd(d, "work", "INBOX", mail.SearchCriteria{}, 2); err != nil { + t.Fatalf("SearchCmd: %v", err) + } + res := decode(t, buf.Bytes()) + if res["error"] != false { + t.Fatalf("unexpected error envelope: %v", res) + } + data := res["data"].(map[string]any) + msgs := data["messages"].([]any) + // With pre-filter cap (old bug): limit=2 would have fetched UIDs 1,2 then + // filtered, yielding only 1 visible. Correct behaviour: 2 visible (1,3). + if len(msgs) != 2 { + t.Fatalf("want 2 visible messages, got %d: %v", len(msgs), msgs) + } +} + func TestAckAdvancesStateAndFiltered(t *testing.T) { fm := &fakeMailer{ uidValidity: 1, maxUID: 100,