From 4c8faf40ec303fc759c28c3a97bf5ff1a2ddfb81 Mon Sep 17 00:00:00 2001 From: vickydotbat Date: Wed, 20 May 2026 16:02:26 +0200 Subject: [PATCH] Generic user_bottom wiki block --- internal/topdata/wiki_deploy_test.go | 43 ++++++++++++---------------- internal/topdata/wiki_native.go | 2 +- internal/topdata/wiki_native_test.go | 31 +++++++++++++++++--- internal/topdata/wiki_preserve.go | 3 +- internal/topdata/wiki_template.go | 2 +- 5 files changed, 49 insertions(+), 32 deletions(-) diff --git a/internal/topdata/wiki_deploy_test.go b/internal/topdata/wiki_deploy_test.go index b437dc5..dd6ba88 100644 --- a/internal/topdata/wiki_deploy_test.go +++ b/internal/topdata/wiki_deploy_test.go @@ -156,9 +156,9 @@ func TestMergeManagedContentPreservesUserTopAndBottomSections(t *testing.T) { `

User-written overview.

`, ``, `

Old generated body.

`, - ``, - `

Notes

User note.

`, - ``, + ``, + `

User-written bottom content.

`, + ``, ``, }, "\n") generated := strings.Join([]string{ @@ -169,16 +169,16 @@ func TestMergeManagedContentPreservesUserTopAndBottomSections(t *testing.T) { `

`, ``, `

New generated body.

`, - ``, - `

Notes

`, - ``, + ``, + `

`, + ``, ``, }, "\n") merged := mergeManagedContent(existing, generated) for _, expected := range []string{ "

User-written overview.

", - "

Notes

User note.

", + "

User-written bottom content.

", "

New generated body.

", } { if !strings.Contains(merged, expected) { @@ -393,10 +393,9 @@ func TestDeployWikiAdoptsExistingNodeBBPageWhenManifestIsMissingWithoutCreate(t

Acolyte

Generated acolyte page

- -

Notes

+

- + ` if err := os.WriteFile(filepath.Join(sourceDir, "classes", "acolyte.html"), []byte(generated), 0644); err != nil { t.Fatalf("write source page: %v", err) @@ -406,10 +405,9 @@ func TestDeployWikiAdoptsExistingNodeBBPageWhenManifestIsMissingWithoutCreate(t

Acolyte

Old acolyte page

- -

Notes

+

Keep this remote note.

- + ` createCalls := 0 @@ -500,14 +498,9 @@ func TestDeployWikiMergesHTMLManagedAndManualRegions(t *testing.T) {

Athletics

Generated athletics page

- -

Notes

+

- - -

See Also

-

- + ` if err := os.WriteFile(filepath.Join(sourceDir, "skills", "athletics.html"), []byte(generated), 0644); err != nil { t.Fatalf("write source page: %v", err) @@ -517,10 +510,9 @@ func TestDeployWikiMergesHTMLManagedAndManualRegions(t *testing.T) {

Athletics

Old generated text

- -

Notes

+

Keep this human note.

- + ` manifestPath := filepath.Join(root, "deploy-manifest.json") if err := saveDeployManifest(manifestPath, wikiDeployManifest{ @@ -572,9 +564,12 @@ func TestDeployWikiMergesHTMLManagedAndManualRegions(t *testing.T) { if result.Updated != 1 { t.Fatalf("expected one update, got %#v", result) } - if !containsAll(updated, "

Generated athletics page

", "

Keep this human note.

", `manual:start id="see_also"`) { + if !containsAll(updated, "

Generated athletics page

", "

Keep this human note.

", `manual:start id="user_bottom"`) { t.Fatalf("expected update to replace managed HTML and preserve/bootstrap manual regions:\n%s", updated) } + if strings.Contains(updated, `manual:start id="notes"`) || strings.Contains(updated, `manual:start id="see_also"`) { + t.Fatalf("expected update to omit legacy split bottom manual regions:\n%s", updated) + } } func TestDeployWikiUpdateAcquiresWestgateWikiEditLock(t *testing.T) { diff --git a/internal/topdata/wiki_native.go b/internal/topdata/wiki_native.go index fc54aa8..c2f090c 100644 --- a/internal/topdata/wiki_native.go +++ b/internal/topdata/wiki_native.go @@ -246,7 +246,7 @@ func loadWikiManualSections(p *project.Project) []wikiManualSection { switch section.ID { case "user_top": section.Alias = "UserTopSection" - case "notes": + case "user_bottom": section.Alias = "UserBottomSection" } } diff --git a/internal/topdata/wiki_native_test.go b/internal/topdata/wiki_native_test.go index cf30351..4d2acbf 100644 --- a/internal/topdata/wiki_native_test.go +++ b/internal/topdata/wiki_native_test.go @@ -59,8 +59,11 @@ func TestBuildNativeGeneratesAndSkipsWikiPages(t *testing.T) { if strings.Contains(text, "[//]: #") || strings.Contains(text, "") { t.Fatalf("expected generated HTML to omit DokuWiki-era syntax:\n%s", text) } - if !strings.Contains(text, ``) || !strings.Contains(text, "

See Also

") { - t.Fatalf("expected generated page to include manual section placeholders:\n%s", text) + if !strings.Contains(text, ``) { + t.Fatalf("expected generated page to include user_bottom manual section placeholder:\n%s", text) + } + if strings.Contains(text, `manual:start id="notes"`) || strings.Contains(text, `manual:start id="see_also"`) || strings.Contains(text, "

See Also

") { + t.Fatalf("expected generated page to omit legacy split bottom manual sections:\n%s", text) } statusPath := filepath.Join(root, ".cache", "wiki", "pages", "meta", "wikistatus.html") statusRaw, err := os.ReadFile(statusPath) @@ -130,6 +133,26 @@ func countGeneratedWikiHTMLFiles(t *testing.T, root string) int { return count } +func TestDefaultWikiManualSectionsUseSingleUserBottomBlock(t *testing.T) { + sections := defaultWikiManualSections() + if len(sections) != 2 { + t.Fatalf("expected top and bottom manual sections only, got %#v", sections) + } + expected := map[string]string{ + "user_top": "UserTopSection", + "user_bottom": "UserBottomSection", + } + for _, section := range sections { + alias, ok := expected[section.ID] + if !ok { + t.Fatalf("unexpected default manual section %#v", section) + } + if section.Alias != alias { + t.Fatalf("expected alias %q for %q, got %q", alias, section.ID, section.Alias) + } + } +} + func TestWikiClassNamePrefersFullNameInsteadOfShortCode(t *testing.T) { ctx := &wikiContext{} got := ctx.resolveRowName("classes", map[string]any{ @@ -158,7 +181,7 @@ func TestWikiTemplateRendersFieldsFormattersAndPreservedTopSection(t *testing.T) }, ManualSections: []wikiManualSection{ {ID: "user_top", Alias: "UserTopSection", InitialHTML: "

"}, - {ID: "notes", Alias: "UserBottomSection", InitialHTML: "

Notes

"}, + {ID: "user_bottom", Alias: "UserBottomSection", InitialHTML: "

"}, }, } @@ -181,7 +204,7 @@ func TestWikiTemplateRendersFieldsFormattersAndPreservedTopSection(t *testing.T) "

Skill Points: 4

", "This is a new class!", "

Acolyte description.

", - ``, + ``, } { if !strings.Contains(got, expected) { t.Fatalf("expected %q in rendered template:\n%s", expected, got) diff --git a/internal/topdata/wiki_preserve.go b/internal/topdata/wiki_preserve.go index 5359bab..f5f67d6 100644 --- a/internal/topdata/wiki_preserve.go +++ b/internal/topdata/wiki_preserve.go @@ -49,7 +49,6 @@ func normalizePreservedSectionBodies(content string) string { func defaultWikiManualSections() []wikiManualSection { return []wikiManualSection{ {ID: "user_top", Alias: "UserTopSection", Heading: "", InitialHTML: "

"}, - {ID: "notes", Alias: "UserBottomSection", Heading: "Notes", InitialHTML: "

Notes

"}, - {ID: "see_also", Heading: "See Also", InitialHTML: "

See Also

"}, + {ID: "user_bottom", Alias: "UserBottomSection", Heading: "", InitialHTML: "

"}, } } diff --git a/internal/topdata/wiki_template.go b/internal/topdata/wiki_template.go index 02621a6..46bda2c 100644 --- a/internal/topdata/wiki_template.go +++ b/internal/topdata/wiki_template.go @@ -158,7 +158,7 @@ func wikiManualSectionForAlias(sections []wikiManualSection, alias string) (wiki } case "UserBottomSection": for _, section := range sections { - if section.ID == "notes" { + if section.ID == "user_bottom" { return section, true } }