Files
mopac-discourse-go/search_test.go
T
mrcharles 14cdaa0a2d feat: search — GET /search.json with grouped hits
Client.Search(term, page) url-encodes the term (operators like
@user / #category / order:latest pass through) and decodes the four
hit groups Discourse returns: posts (with blurb and highlighted
topic title), topics, users and categories. Empty term is rejected
locally with ErrInvalidRequest; server failures keep the typed
error classes. Fake-server tests cover encoding, parsing and the
403 path.

Part of Redmine 507 (Discourse Go client): search is how the 495
briefing pipeline finds landing spots and prior threads.
2026-08-29 16:25:29 -05:00

71 lines
2.0 KiB
Go

package discourse
import (
"context"
"errors"
"testing"
)
func TestSearchRequiresTerm(t *testing.T) {
f := newFake(t)
c := testClient(t, f)
_, err := c.Search(context.Background(), SearchRequest{})
if !errors.Is(err, ErrInvalidRequest) {
t.Fatalf("want ErrInvalidRequest for empty term, got %v", err)
}
if f.saw("/search.json") {
t.Fatal("no request should have been sent for an empty term")
}
}
func TestSearchQueriesAndParses(t *testing.T) {
f := newFake(t)
c := testClient(t, f)
res, err := c.Search(context.Background(), SearchRequest{Term: "fleet briefing"})
if err != nil {
t.Fatalf("Search: %v", err)
}
if !f.sawQuery("/search.json", "term=fleet+briefing") {
t.Fatal("search term not sent as the term= query parameter")
}
if len(res.Posts) != 1 || res.Posts[0].TopicID != 12 || res.Posts[0].Username != "reachableceo" {
t.Fatalf("posts not parsed: %+v", res.Posts)
}
if res.Posts[0].Blurb == "" {
t.Fatal("blurb not parsed")
}
if len(res.Topics) != 1 || res.Topics[0].Title != "Fleet briefing 2026-09-01" {
t.Fatalf("topics not parsed: %+v", res.Topics)
}
if len(res.Users) != 1 || res.Users[0].Username != "reachableceo" {
t.Fatalf("users not parsed: %+v", res.Users)
}
if len(res.Categories) != 1 || res.Categories[0].Slug != "mopac-briefings" {
t.Fatalf("categories not parsed: %+v", res.Categories)
}
}
func TestSearchEncodesTermAndPage(t *testing.T) {
f := newFake(t)
c := testClient(t, f)
if _, err := c.Search(context.Background(), SearchRequest{Term: "a b&c=d", Page: 2}); err != nil {
t.Fatalf("Search: %v", err)
}
if !f.sawQuery("/search.json", "term=a+b%26c%3Dd") {
t.Fatal("term not url-encoded (a b&c=d must not smuggle extra params)")
}
if !f.sawQuery("/search.json", "page=2") {
t.Fatal("page not sent as the page= query parameter")
}
}
func TestSearchTypedErrors(t *testing.T) {
f := newFake(t)
c := testClient(t, f)
f.searchFail = 403
_, err := c.Search(context.Background(), SearchRequest{Term: "x"})
if !errors.Is(err, ErrForbidden) {
t.Fatalf("want ErrForbidden, got %v", err)
}
}