package discourse import ( "context" "errors" "strings" "testing" ) func TestSendMessageRequiresTargets(t *testing.T) { f := newFake(t) c := testClient(t, f) _, err := c.SendMessage(context.Background(), SendMessageRequest{Title: "t", Raw: "r"}) if !errors.Is(err, ErrInvalidRequest) { t.Fatalf("want ErrInvalidRequest without targets, got %v", err) } if f.saw("/posts.json") { t.Fatal("no request should have been sent without targets") } } func TestSendMessageRequiresTitleAndRaw(t *testing.T) { c, _ := New("https://ok.example", testKey, "") if _, err := c.SendMessage(context.Background(), SendMessageRequest{Raw: "r", TargetUsernames: []string{"ops"}}); !errors.Is(err, ErrInvalidRequest) { t.Fatalf("missing title: want ErrInvalidRequest, got %v", err) } if _, err := c.SendMessage(context.Background(), SendMessageRequest{Title: "t", TargetUsernames: []string{"ops"}}); !errors.Is(err, ErrInvalidRequest) { t.Fatalf("missing raw: want ErrInvalidRequest, got %v", err) } } func TestSendMessage(t *testing.T) { f := newFake(t) c := testClient(t, f) res, err := c.SendMessage(context.Background(), SendMessageRequest{ Title: "Fleet ping", Raw: "check the briefing", TargetUsernames: []string{"ops", "reachableceo"}, }) if err != nil { t.Fatalf("SendMessage: %v", err) } if res.TopicID == 0 || res.TopicSlug == "" { t.Fatalf("want topic ids in result, got %+v", res) } if u := res.URL(f.srv.URL); !strings.Contains(u, "/t/fleet-ping/") { t.Fatalf("PM URL should be /t//, got %q", u) } body := f.lastBody for _, want := range []string{`"title":"Fleet ping"`, `"target_usernames":"ops,reachableceo"`} { if !strings.Contains(body, want) { t.Fatalf("wire body missing %s: %s", want, body) } } if strings.Contains(body, `"target_usernames":["`) { t.Fatalf("targets must be comma-joined, not a JSON array: %s", body) } if got := f.pms; len(got) != 1 || got[0].TopicID != res.TopicID || got[0].Title != "Fleet ping" { t.Fatalf("fake did not record the PM: %+v", got) } if got := f.pms[0].Targets; len(got) != 2 || got[0] != "ops" || got[1] != "reachableceo" { t.Fatalf("recipients not recorded: %+v", got) } } func TestSendMessageGroupAndEmailTargets(t *testing.T) { f := newFake(t) c := testClient(t, f) _, err := c.SendMessage(context.Background(), SendMessageRequest{ Title: "Bulk", Raw: "hi", TargetGroupNames: []string{"staff", "admins"}, TargetEmails: []string{"a@x.test"}, }) if err != nil { t.Fatalf("SendMessage: %v", err) } for _, want := range []string{`"target_group_names":"staff,admins"`, `"target_emails":"a@x.test"`} { if !strings.Contains(f.lastBody, want) { t.Fatalf("wire body missing %s: %s", want, f.lastBody) } } } func TestSendMessageForbiddenIsTyped(t *testing.T) { f := newFake(t) c := testClient(t, f) _, err := c.SendMessage(context.Background(), SendMessageRequest{ Title: "nope", Raw: "x", TargetUsernames: []string{"denied"}, }) if !errors.Is(err, ErrForbidden) { t.Fatalf("want ErrForbidden for undeliverable recipient, got %v", err) } }