fix(cli): search limit counts visible results, filter before cap
Pass 0 (unlimited) to m.Search so the mail layer returns all matching headers; the existing post-filter loop already caps at the caller's limit, mirroring ListCmd. Add TestSearchLimitCountsVisibleOnly to prove filtering happens before the cap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -187,7 +187,7 @@ func SearchCmd(d Deps, account, folder string, sc mail.SearchCriteria, limit int
|
|||||||
return d.emit(*fail)
|
return d.emit(*fail)
|
||||||
}
|
}
|
||||||
defer done()
|
defer done()
|
||||||
headers, err := m.Search(folder, sc, limit)
|
headers, err := m.Search(folder, sc, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return d.emit(Failure(CodeNetwork, err.Error()))
|
return d.emit(Failure(CodeNetwork, err.Error()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
func TestAckAdvancesStateAndFiltered(t *testing.T) {
|
||||||
fm := &fakeMailer{
|
fm := &fakeMailer{
|
||||||
uidValidity: 1, maxUID: 100,
|
uidValidity: 1, maxUID: 100,
|
||||||
|
|||||||
Reference in New Issue
Block a user