forked from Gitlink/gitlink-cli
feat: add wiki +view,+create,+update,+delete shortcuts with tests
This commit is contained in:
parent
1e28d3775d
commit
0362f3f604
|
|
@ -1,6 +1,7 @@
|
|||
package wiki
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
||||
"github.com/gitlink-org/gitlink-cli/shortcuts/common"
|
||||
|
|
@ -23,9 +24,115 @@ func Shortcuts() []*common.Shortcut {
|
|||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "view",
|
||||
Description: "View a wiki page",
|
||||
Flags: []common.Flag{
|
||||
{Name: "slug", Short: "s", Usage: "Wiki page slug", Required: true},
|
||||
},
|
||||
Run: func(ctx *common.RuntimeContext) error {
|
||||
if err := ctx.ResolveOwnerRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
slug, err := ctx.RequireArg("slug")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
env, err := ctx.CallAPI("GET", wikiPagePath(ctx, slug), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "create",
|
||||
Description: "Create a wiki page",
|
||||
Flags: []common.Flag{
|
||||
{Name: "title", Short: "t", Usage: "Wiki page title", Required: true},
|
||||
{Name: "body", Short: "b", Usage: "Wiki page content", Required: true},
|
||||
},
|
||||
Run: func(ctx *common.RuntimeContext) error {
|
||||
if err := ctx.ResolveOwnerRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
title, err := ctx.RequireArg("title")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body, err := ctx.RequireArg("body")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
payload := map[string]interface{}{
|
||||
"title": title,
|
||||
"content_base64": base64.StdEncoding.EncodeToString([]byte(body)),
|
||||
}
|
||||
env, err := ctx.CallAPI("POST", wikiPagesPath(ctx), payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "update",
|
||||
Description: "Update a wiki page",
|
||||
Flags: []common.Flag{
|
||||
{Name: "slug", Short: "s", Usage: "Wiki page slug", Required: true},
|
||||
{Name: "title", Short: "t", Usage: "New title"},
|
||||
{Name: "body", Short: "b", Usage: "New content"},
|
||||
},
|
||||
Run: func(ctx *common.RuntimeContext) error {
|
||||
if err := ctx.ResolveOwnerRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
slug, err := ctx.RequireArg("slug")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
payload := map[string]interface{}{}
|
||||
if title := ctx.Arg("title"); title != "" {
|
||||
payload["title"] = title
|
||||
}
|
||||
if body := ctx.Arg("body"); body != "" {
|
||||
payload["content_base64"] = base64.StdEncoding.EncodeToString([]byte(body))
|
||||
}
|
||||
env, err := ctx.CallAPI("PATCH", wikiPagePath(ctx, slug), payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "delete",
|
||||
Description: "Delete a wiki page",
|
||||
Flags: []common.Flag{
|
||||
{Name: "slug", Short: "s", Usage: "Wiki page slug", Required: true},
|
||||
},
|
||||
Run: func(ctx *common.RuntimeContext) error {
|
||||
if err := ctx.ResolveOwnerRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
slug, err := ctx.RequireArg("slug")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
env, err := ctx.CallAPI("DELETE", wikiPagePath(ctx, slug), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func wikiPagesPath(ctx *common.RuntimeContext) string {
|
||||
return fmt.Sprintf("/%s/%s/wiki/pages", ctx.Owner, ctx.Repo)
|
||||
}
|
||||
|
||||
func wikiPagePath(ctx *common.RuntimeContext, slug string) string {
|
||||
return fmt.Sprintf("/%s/%s/wiki/pages/%s", ctx.Owner, ctx.Repo, slug)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package wiki
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
|
@ -10,6 +11,8 @@ import (
|
|||
"github.com/gitlink-org/gitlink-cli/shortcuts/common"
|
||||
)
|
||||
|
||||
// --- List ---
|
||||
|
||||
func TestWikiList(t *testing.T) {
|
||||
server := newWikiTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
assertRequest(t, r, "GET", "/owner/repo/wiki/pages.json")
|
||||
|
|
@ -28,6 +31,99 @@ func TestWikiList(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// --- View ---
|
||||
|
||||
func TestWikiView(t *testing.T) {
|
||||
server := newWikiTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
assertRequest(t, r, "GET", "/owner/repo/wiki/pages/home.json")
|
||||
writeJSON(t, w, map[string]interface{}{
|
||||
"title": "Home",
|
||||
"slug": "home",
|
||||
"content_base64": base64.StdEncoding.EncodeToString([]byte("Welcome to the wiki")),
|
||||
})
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
if err := runWikiShortcut(t, server, "view", map[string]string{"slug": "home"}); err != nil {
|
||||
t.Fatalf("view shortcut failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// --- Create ---
|
||||
|
||||
func TestWikiCreate(t *testing.T) {
|
||||
server := newWikiTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
assertRequest(t, r, "POST", "/owner/repo/wiki/pages.json")
|
||||
body := decodeJSON(t, r)
|
||||
assertEqual(t, body["title"], "TestPage")
|
||||
decoded, err := base64.StdEncoding.DecodeString(body["content_base64"].(string))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to decode content_base64: %v", err)
|
||||
}
|
||||
assertEqual(t, string(decoded), "Hello World")
|
||||
|
||||
writeJSON(t, w, map[string]interface{}{
|
||||
"title": "TestPage",
|
||||
"slug": "TestPage",
|
||||
})
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
if err := runWikiShortcut(t, server, "create", map[string]string{
|
||||
"title": "TestPage",
|
||||
"body": "Hello World",
|
||||
}); err != nil {
|
||||
t.Fatalf("create shortcut failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// --- Update ---
|
||||
|
||||
func TestWikiUpdate(t *testing.T) {
|
||||
server := newWikiTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
assertRequest(t, r, "PATCH", "/owner/repo/wiki/pages/home.json")
|
||||
body := decodeJSON(t, r)
|
||||
assertEqual(t, body["title"], "Updated Title")
|
||||
decoded, err := base64.StdEncoding.DecodeString(body["content_base64"].(string))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to decode content_base64: %v", err)
|
||||
}
|
||||
assertEqual(t, string(decoded), "Updated content")
|
||||
|
||||
writeJSON(t, w, map[string]interface{}{
|
||||
"title": "Updated Title",
|
||||
"slug": "home",
|
||||
})
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
if err := runWikiShortcut(t, server, "update", map[string]string{
|
||||
"slug": "home",
|
||||
"title": "Updated Title",
|
||||
"body": "Updated content",
|
||||
}); err != nil {
|
||||
t.Fatalf("update shortcut failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// --- Delete ---
|
||||
|
||||
func TestWikiDelete(t *testing.T) {
|
||||
server := newWikiTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
assertRequest(t, r, "DELETE", "/owner/repo/wiki/pages/old-page.json")
|
||||
writeJSON(t, w, map[string]interface{}{
|
||||
"message": "deleted",
|
||||
})
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
if err := runWikiShortcut(t, server, "delete", map[string]string{
|
||||
"slug": "old-page",
|
||||
}); err != nil {
|
||||
t.Fatalf("delete shortcut failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// --- test helpers ---
|
||||
|
||||
func runWikiShortcut(t *testing.T, server *httptest.Server, name string, args map[string]string) error {
|
||||
|
|
@ -79,3 +175,19 @@ func writeJSON(t *testing.T, w http.ResponseWriter, payload interface{}) {
|
|||
t.Fatalf("failed to write response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func decodeJSON(t *testing.T, r *http.Request) map[string]interface{} {
|
||||
t.Helper()
|
||||
var m map[string]interface{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&m); err != nil {
|
||||
t.Fatalf("failed to decode request body: %v", err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func assertEqual(t *testing.T, got, want interface{}) {
|
||||
t.Helper()
|
||||
if got != want {
|
||||
t.Fatalf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue