From 2f1809818591f4934cf10c165d1f358611a686d4 Mon Sep 17 00:00:00 2001 From: Virgil Date: Wed, 1 Apr 2026 07:16:48 +0000 Subject: [PATCH] feat: add markup rendering endpoint Co-Authored-By: Virgil --- docs/api-contract.md | 1 + misc.go | 11 +++++++++++ misc_test.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/docs/api-contract.md b/docs/api-contract.md index f44c770..487d9c8 100644 --- a/docs/api-contract.md +++ b/docs/api-contract.md @@ -138,6 +138,7 @@ Coverage notes: rows list direct tests when a symbol is named in test names or r | method | MiscService.ListGitignoreTemplates | `func (s *MiscService) ListGitignoreTemplates(ctx context.Context) ([]string, error)` | ListGitignoreTemplates returns all available gitignore template names. | `TestMiscService_Good_ListGitignoreTemplates` | | method | MiscService.ListLicenses | `func (s *MiscService) ListLicenses(ctx context.Context) ([]types.LicensesTemplateListEntry, error)` | ListLicenses returns all available licence templates. | `TestMiscService_Good_ListLicenses` | | method | MiscService.RenderMarkdown | `func (s *MiscService) RenderMarkdown(ctx context.Context, text, mode string) (string, error)` | RenderMarkdown renders markdown text to HTML. The response is raw HTML text, not JSON. | `TestMiscService_Good_RenderMarkdown` | +| method | MiscService.RenderMarkup | `func (s *MiscService) RenderMarkup(ctx context.Context, text, mode string) (string, error)` | RenderMarkup renders markup text to HTML. The response is raw HTML text, not JSON. | `TestMiscService_Good_RenderMarkup` | | method | MiscService.RenderMarkdownRaw | `func (s *MiscService) RenderMarkdownRaw(ctx context.Context, text string) (string, error)` | RenderMarkdownRaw renders raw markdown text to HTML. The request body is sent as text/plain and the response is raw HTML text, not JSON. | `TestMiscService_RenderMarkdownRaw_Good` | | method | NotificationService.GetThread | `func (s *NotificationService) GetThread(ctx context.Context, id int64) (*types.NotificationThread, error)` | GetThread returns a single notification thread by ID. | `TestNotificationService_Bad_NotFound`, `TestNotificationService_Good_GetThread` | | method | NotificationService.Iter | `func (s *NotificationService) Iter(ctx context.Context) iter.Seq2[types.NotificationThread, error]` | Iter returns an iterator over all notifications for the authenticated user. | No direct tests. | diff --git a/misc.go b/misc.go index df307c9..a2ebda4 100644 --- a/misc.go +++ b/misc.go @@ -35,6 +35,17 @@ func (s *MiscService) RenderMarkdown(ctx context.Context, text, mode string) (st return string(data), nil } +// RenderMarkup renders markup text to HTML. The response is raw HTML text, +// not JSON. +func (s *MiscService) RenderMarkup(ctx context.Context, text, mode string) (string, error) { + body := types.MarkupOption{Text: text, Mode: mode} + data, err := s.client.PostRaw(ctx, "/api/v1/markup", body) + if err != nil { + return "", err + } + return string(data), nil +} + // RenderMarkdownRaw renders raw markdown text to HTML. The request body is // sent as text/plain and the response is raw HTML text, not JSON. func (s *MiscService) RenderMarkdownRaw(ctx context.Context, text string) (string, error) { diff --git a/misc_test.go b/misc_test.go index 791860d..bf2fe2b 100644 --- a/misc_test.go +++ b/misc_test.go @@ -46,6 +46,40 @@ func TestMiscService_RenderMarkdown_Good(t *testing.T) { } } +func TestMiscService_RenderMarkup_Good(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + t.Errorf("expected POST, got %s", r.Method) + } + if r.URL.Path != "/api/v1/markup" { + t.Errorf("wrong path: %s", r.URL.Path) + } + var opts types.MarkupOption + if err := json.NewDecoder(r.Body).Decode(&opts); err != nil { + t.Fatal(err) + } + if opts.Text != "**Hello**" { + t.Errorf("got text=%q, want %q", opts.Text, "**Hello**") + } + if opts.Mode != "gfm" { + t.Errorf("got mode=%q, want %q", opts.Mode, "gfm") + } + w.Header().Set("Content-Type", "text/html") + w.Write([]byte("

Hello

\n")) + })) + defer srv.Close() + + f := NewForge(srv.URL, "tok") + html, err := f.Misc.RenderMarkup(context.Background(), "**Hello**", "gfm") + if err != nil { + t.Fatal(err) + } + want := "

Hello

\n" + if html != want { + t.Errorf("got %q, want %q", html, want) + } +} + func TestMiscService_RenderMarkdownRaw_Good(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost {