// SPDX-Licence-Identifier: EUPL-1.2 package help import ( "encoding/json" "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // testCatalog builds a small catalog for generator tests. func testCatalog() *Catalog { c := &Catalog{ topics: make(map[string]*Topic), index: newSearchIndex(), } c.Add(&Topic{ ID: "getting-started", Title: "Getting Started", Content: "# Getting Started\n\nWelcome to the **guide**.\n", Tags: []string{"intro"}, Sections: []Section{ {ID: "getting-started", Title: "Getting Started", Level: 1}, }, }) c.Add(&Topic{ ID: "config", Title: "Configuration", Content: "# Configuration\n\nSet up your environment.\n", Tags: []string{"setup"}, Related: []string{"getting-started"}, }) return c } func TestGenerate_Good_FileStructure(t *testing.T) { dir := t.TempDir() catalog := testCatalog() err := Generate(catalog, dir) require.NoError(t, err) // Verify expected file structure expectedFiles := []string{ "index.html", "search.html", "search-index.json", "404.html", "topics/getting-started.html", "topics/config.html", } for _, f := range expectedFiles { path := filepath.Join(dir, f) _, err := os.Stat(path) assert.NoError(t, err, "expected file %s to exist", f) } } func TestGenerate_Good_IndexContainsTopics(t *testing.T) { dir := t.TempDir() catalog := testCatalog() err := Generate(catalog, dir) require.NoError(t, err) content, err := os.ReadFile(filepath.Join(dir, "index.html")) require.NoError(t, err) html := string(content) assert.Contains(t, html, "Getting Started") assert.Contains(t, html, "Configuration") } func TestGenerate_Good_TopicContainsRenderedMarkdown(t *testing.T) { dir := t.TempDir() catalog := testCatalog() err := Generate(catalog, dir) require.NoError(t, err) content, err := os.ReadFile(filepath.Join(dir, "topics", "getting-started.html")) require.NoError(t, err) html := string(content) assert.Contains(t, html, "Getting Started") assert.Contains(t, html, "guide") } func TestGenerate_Good_SearchIndexJSON(t *testing.T) { dir := t.TempDir() catalog := testCatalog() err := Generate(catalog, dir) require.NoError(t, err) content, err := os.ReadFile(filepath.Join(dir, "search-index.json")) require.NoError(t, err) var entries []searchIndexEntry require.NoError(t, json.Unmarshal(content, &entries)) assert.Len(t, entries, 2, "search index should contain all topics") // Verify fields are populated ids := make(map[string]bool) for _, e := range entries { ids[e.ID] = true assert.NotEmpty(t, e.Title) assert.NotEmpty(t, e.Content) } assert.True(t, ids["getting-started"]) assert.True(t, ids["config"]) } func TestGenerate_Good_404Exists(t *testing.T) { dir := t.TempDir() catalog := testCatalog() err := Generate(catalog, dir) require.NoError(t, err) content, err := os.ReadFile(filepath.Join(dir, "404.html")) require.NoError(t, err) html := string(content) assert.Contains(t, html, "404") assert.Contains(t, html, "not found") } func TestGenerate_Good_EmptyDir(t *testing.T) { dir := t.TempDir() catalog := testCatalog() // Should succeed in an empty directory err := Generate(catalog, dir) assert.NoError(t, err) } func TestGenerate_Good_OverwriteExisting(t *testing.T) { dir := t.TempDir() catalog := testCatalog() // Generate once err := Generate(catalog, dir) require.NoError(t, err) // Generate again -- should overwrite without error err = Generate(catalog, dir) assert.NoError(t, err) // Verify files still exist and are valid content, err := os.ReadFile(filepath.Join(dir, "index.html")) require.NoError(t, err) assert.Contains(t, string(content), "Getting Started") } func TestGenerate_Good_SearchPageHasScript(t *testing.T) { dir := t.TempDir() catalog := testCatalog() err := Generate(catalog, dir) require.NoError(t, err) content, err := os.ReadFile(filepath.Join(dir, "search.html")) require.NoError(t, err) html := string(content) assert.Contains(t, html, "