diff --git a/shortcuts/wiki/wiki.go b/shortcuts/wiki/wiki.go index 839ef43..1fed0ed 100644 --- a/shortcuts/wiki/wiki.go +++ b/shortcuts/wiki/wiki.go @@ -433,11 +433,17 @@ func cleanSidebar(ctx *common.RuntimeContext, projectID int, pageName string) { return } - target := "[[" + pageName + "]]" + // GitLink appends a ".-" suffix to every page's sub_url on create, so the + // caller usually passes the sub_url here. But the sidebar stores links by + // the clean name (no ".-"). Match both forms so the link is never orphaned. + targets := map[string]bool{ + "[[" + pageName + "]]": true, + "[[" + stripPageSuffix(pageName) + "]]": true, + } lines := strings.Split(sidebar, "\n") var newLines []string for _, line := range lines { - if strings.TrimSpace(line) != target { + if !targets[strings.TrimSpace(line)] { newLines = append(newLines, line) } } @@ -449,6 +455,12 @@ func cleanSidebar(ctx *common.RuntimeContext, projectID int, pageName string) { updateSidebarContent(ctx, projectID, newSidebar, "Remove deleted page "+pageName+" from sidebar") } +// stripPageSuffix removes the trailing ".-" suffix that GitLink appends to a +// page's sub_url. It leaves all other names (including "_Sidebar") untouched. +func stripPageSuffix(name string) string { + return strings.TrimSuffix(name, ".-") +} + // addPageToSidebarDir adds a [[pageName]] link under the specified directory in the sidebar. func addPageToSidebarDir(ctx *common.RuntimeContext, projectID int, pageName, dirName string) error { defer withWikiGateway(ctx)() diff --git a/shortcuts/wiki/wiki_test.go b/shortcuts/wiki/wiki_test.go index 7cf1911..81a91f0 100644 --- a/shortcuts/wiki/wiki_test.go +++ b/shortcuts/wiki/wiki_test.go @@ -190,3 +190,49 @@ func TestWikiDelete(t *testing.T) { expectedSidebar := base64.StdEncoding.EncodeToString([]byte("[[OtherPage]]")) common.AssertEqual(t, sidebarUpdatePayload["content_base64"], expectedSidebar) } + +// TestWikiDeleteStripsSuffix reproduces the real-platform scenario: +// GitLink appends a ".-" suffix to every page's sub_url on create, so the +// caller must pass the sub_url ("OldPage.-") to delete (the clean name 404s). +// But the sidebar stores the link as [[OldPage]] (no suffix). cleanSidebar +// must therefore strip the ".-" suffix when matching, otherwise the link is +// orphaned in the sidebar after deletion. +func TestWikiDeleteStripsSuffix(t *testing.T) { + var sidebarUpdatePayload map[string]interface{} + server := common.NewTestServer(t, func(w http.ResponseWriter, r *http.Request) { + switch { + case r.Method == "GET" && r.URL.Path == "/owner/repo.json": + common.WriteJSON(t, w, map[string]interface{}{"id": float64(123)}) + case r.Method == "DELETE" && r.URL.Path == "/wiki/open/deleteWiki": + common.WriteJSON(t, w, map[string]interface{}{"code": 204}) + case r.Method == "GET" && r.URL.Path == "/wiki/open/getWiki": + common.WriteJSON(t, w, map[string]interface{}{ + "code": 200, + "data": map[string]interface{}{ + // sidebar holds the clean name (no ".-") + "content_base64": base64.StdEncoding.EncodeToString([]byte("[[OldPage]]\n[[OtherPage]]")), + }, + }) + case r.Method == "PUT" && r.URL.Path == "/wiki/open/updateWiki": + sidebarUpdatePayload = common.DecodeJSON(t, r) + common.WriteJSON(t, w, map[string]interface{}{"code": 200}) + default: + t.Fatalf("unexpected request: %s %s", r.Method, r.URL.Path) + } + }) + defer server.Close() + + // Caller passes the sub_url (with ".-"), as required by the real API. + ctx := common.NewTestContext(t, server, "owner", "repo", map[string]string{ + "name": "OldPage.-", + }) + if err := common.RunShortcut(t, Shortcuts(), "delete", ctx); err != nil { + t.Fatalf("delete failed: %v", err) + } + + if sidebarUpdatePayload == nil { + t.Fatal("expected sidebar to be updated to remove [[OldPage]], but no update was sent") + } + expectedSidebar := base64.StdEncoding.EncodeToString([]byte("[[OtherPage]]")) + common.AssertEqual(t, sidebarUpdatePayload["content_base64"], expectedSidebar) +}