|
1 | 1 | package docs |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "os" |
5 | | - "path/filepath" |
6 | | - "testing" |
| 4 | + "os" |
| 5 | + "path/filepath" |
| 6 | + "testing" |
7 | 7 |
|
8 | | - "github.com/spf13/cobra" |
9 | | - "github.com/stretchr/testify/assert" |
10 | | - "gopkg.in/yaml.v3" |
| 8 | + "github.com/spf13/cobra" |
| 9 | + "github.com/stretchr/testify/assert" |
| 10 | + "gopkg.in/yaml.v3" |
11 | 11 | ) |
12 | 12 |
|
13 | 13 | // Test getFileName logic for level handling and GroupID usage. |
14 | 14 | func TestGetFileName(t *testing.T) { |
15 | | - cmdNoGroup := &cobra.Command{Use: "scan", Short: "scan"} |
16 | | - cmdGroup := &cobra.Command{Use: "enum", GroupID: "enumeration"} |
| 15 | + cmdNoGroup := &cobra.Command{Use: "scan", Short: "scan"} |
| 16 | + cmdGroup := &cobra.Command{Use: "enum", GroupID: "enumeration"} |
17 | 17 |
|
18 | | - assert.Equal(t, "scan.md", getFileName(cmdNoGroup, 1)) |
19 | | - assert.Equal(t, "enumeration.md", getFileName(cmdGroup, 1)) |
20 | | - assert.Equal(t, "scan.md", getFileName(cmdNoGroup, 2)) // level >1 ignores GroupID logic |
| 18 | + assert.Equal(t, "scan.md", getFileName(cmdNoGroup, 1)) |
| 19 | + assert.Equal(t, "enumeration.md", getFileName(cmdGroup, 1)) |
| 20 | + assert.Equal(t, "scan.md", getFileName(cmdNoGroup, 2)) // level >1 ignores GroupID logic |
21 | 21 | } |
22 | 22 |
|
23 | 23 | // Test displayName title casing and GroupID preference. |
24 | 24 | func TestDisplayName(t *testing.T) { |
25 | | - cmdNoGroup := &cobra.Command{Use: "list"} |
26 | | - cmdGroup := &cobra.Command{Use: "enum", GroupID: "gitlab pentest"} |
| 25 | + cmdNoGroup := &cobra.Command{Use: "list"} |
| 26 | + cmdGroup := &cobra.Command{Use: "enum", GroupID: "gitlab pentest"} |
27 | 27 |
|
28 | | - assert.Equal(t, "List", displayName(cmdNoGroup, 1)) |
29 | | - assert.Equal(t, "Gitlab Pentest", displayName(cmdGroup, 1)) // Title case applied |
30 | | - assert.Equal(t, "Enum", displayName(cmdGroup, 2)) // deeper level uses Name |
| 28 | + assert.Equal(t, "List", displayName(cmdNoGroup, 1)) |
| 29 | + assert.Equal(t, "Gitlab Pentest", displayName(cmdGroup, 1)) // Title case applied |
| 30 | + assert.Equal(t, "Enum", displayName(cmdGroup, 2)) // deeper level uses Name |
31 | 31 | } |
32 | 32 |
|
33 | 33 | // buildNav should create index.md for commands with children and .md file for leaves. |
34 | 34 | func TestBuildNav(t *testing.T) { |
35 | | - root := &cobra.Command{Use: "pipeleak"} |
36 | | - parent := &cobra.Command{Use: "alpha"} |
37 | | - leaf := &cobra.Command{Use: "scan", Run: func(cmd *cobra.Command, args []string) {}} |
38 | | - parent.AddCommand(leaf) |
39 | | - root.AddCommand(parent) |
40 | | - |
41 | | - entry := buildNav(root, 0, "") |
42 | | - assert.Equal(t, "Pipeleak", entry.Label) |
43 | | - assert.Len(t, entry.Children, 1) |
44 | | - child := entry.Children[0] |
45 | | - assert.Equal(t, "Alpha", child.Label) |
46 | | - assert.Equal(t, filepath.ToSlash("pipeleak/alpha/index.md"), child.FilePath) |
47 | | - assert.Len(t, child.Children, 1) |
48 | | - grand := child.Children[0] |
49 | | - assert.Equal(t, filepath.ToSlash("pipeleak/alpha/scan.md"), grand.FilePath) |
| 35 | + root := &cobra.Command{Use: "pipeleak"} |
| 36 | + parent := &cobra.Command{Use: "alpha"} |
| 37 | + leaf := &cobra.Command{Use: "scan", Run: func(cmd *cobra.Command, args []string) {}} |
| 38 | + parent.AddCommand(leaf) |
| 39 | + root.AddCommand(parent) |
| 40 | + |
| 41 | + entry := buildNav(root, 0, "") |
| 42 | + assert.Equal(t, "Pipeleak", entry.Label) |
| 43 | + assert.Len(t, entry.Children, 1) |
| 44 | + child := entry.Children[0] |
| 45 | + assert.Equal(t, "Alpha", child.Label) |
| 46 | + assert.Equal(t, filepath.ToSlash("pipeleak/alpha/index.md"), child.FilePath) |
| 47 | + assert.Len(t, child.Children, 1) |
| 48 | + grand := child.Children[0] |
| 49 | + assert.Equal(t, filepath.ToSlash("pipeleak/alpha/scan.md"), grand.FilePath) |
50 | 50 | } |
51 | 51 |
|
52 | 52 | // convertNavToYaml should trim pipeleak/ prefix and .md suffix. |
53 | 53 | func TestConvertNavToYaml(t *testing.T) { |
54 | | - entries := []*NavEntry{ |
55 | | - {Label: "Alpha", FilePath: filepath.ToSlash("pipeleak/alpha/index.md"), Children: []*NavEntry{}}, |
56 | | - {Label: "Beta", FilePath: filepath.ToSlash("pipeleak/beta/leaf.md"), Children: []*NavEntry{}}, |
57 | | - } |
58 | | - yamlList := convertNavToYaml(entries) |
59 | | - // Entries become maps with label key |
60 | | - assert.Len(t, yamlList, 2) |
61 | | - // Validate trimming and removal of extension |
62 | | - alphaMap := yamlList[0] |
63 | | - betaMap := yamlList[1] |
64 | | - assert.Equal(t, "alpha/index", alphaMap["Alpha"]) |
65 | | - assert.Equal(t, "beta/leaf", betaMap["Beta"]) |
| 54 | + entries := []*NavEntry{ |
| 55 | + {Label: "Alpha", FilePath: filepath.ToSlash("pipeleak/alpha/index.md"), Children: []*NavEntry{}}, |
| 56 | + {Label: "Beta", FilePath: filepath.ToSlash("pipeleak/beta/leaf.md"), Children: []*NavEntry{}}, |
| 57 | + } |
| 58 | + yamlList := convertNavToYaml(entries) |
| 59 | + // Entries become maps with label key |
| 60 | + assert.Len(t, yamlList, 2) |
| 61 | + // Validate trimming and removal of extension |
| 62 | + alphaMap := yamlList[0] |
| 63 | + betaMap := yamlList[1] |
| 64 | + assert.Equal(t, "alpha/index", alphaMap["Alpha"]) |
| 65 | + assert.Equal(t, "beta/leaf", betaMap["Beta"]) |
66 | 66 | } |
67 | 67 |
|
68 | 68 | // writeMkdocsYaml should create mkdocs.yml with expected keys and nav entries. |
69 | 69 | func TestWriteMkdocsYaml(t *testing.T) { |
70 | | - root := &cobra.Command{Use: "pipeleak"} |
71 | | - alpha := &cobra.Command{Use: "alpha", Run: func(cmd *cobra.Command, args []string) {}} |
72 | | - deepParent := &cobra.Command{Use: "beta"} |
73 | | - deepChild := &cobra.Command{Use: "deep", Run: func(cmd *cobra.Command, args []string) {}} |
74 | | - deepParent.AddCommand(deepChild) |
75 | | - root.AddCommand(alpha) |
76 | | - root.AddCommand(deepParent) |
77 | | - |
78 | | - tmpDir := t.TempDir() |
79 | | - // Change working directory to module root (src/pipeleak) so relative ../../docs resolves correctly |
80 | | - wd, _ := os.Getwd() |
81 | | - rootDir := filepath.Clean(filepath.Join(wd, "..", "..")) |
82 | | - old := wd |
83 | | - if err := os.Chdir(rootDir); err != nil { |
84 | | - t.Fatalf("failed to chdir to root: %v", err) |
85 | | - } |
86 | | - defer func() { _ = os.Chdir(old) }() |
87 | | - |
88 | | - err := writeMkdocsYaml(root, tmpDir, false) |
89 | | - assert.NoError(t, err) |
90 | | - |
91 | | - data, err := os.ReadFile(filepath.Join(tmpDir, "mkdocs.yml")) |
92 | | - assert.NoError(t, err) |
93 | | - |
94 | | - var parsed map[string]interface{} |
95 | | - err = yaml.Unmarshal(data, &parsed) |
96 | | - assert.NoError(t, err) |
97 | | - |
98 | | - // Basic keys exist |
99 | | - assert.Equal(t, "Pipeleak - Pipeline Secrets Scanner", parsed["site_name"]) |
100 | | - assert.Equal(t, "pipeleak", parsed["docs_dir"]) |
101 | | - |
102 | | - // Nav structure assertions |
103 | | - navAny, ok := parsed["nav"].([]interface{}) |
104 | | - assert.True(t, ok) |
105 | | - assert.Equal(t, 4, len(navAny)) // intro, methodology, alpha, beta |
106 | | - |
107 | | - // Introduction entry first |
108 | | - introMap, ok := navAny[0].(map[string]interface{}) |
109 | | - assert.True(t, ok) |
110 | | - assert.Contains(t, introMap, "Introduction") |
111 | | - assert.Equal(t, "/introduction/getting_started/", introMap["Introduction"]) |
112 | | - |
113 | | - // Methodology second |
114 | | - methMap, ok := navAny[1].(map[string]interface{}) |
115 | | - assert.True(t, ok) |
116 | | - assert.Contains(t, methMap, "Methodology") |
117 | | - |
118 | | - // Command entries appear after methodology |
119 | | - foundAlpha := false |
120 | | - foundBeta := false |
121 | | - for _, item := range navAny[2:] { |
122 | | - if m, ok := item.(map[string]interface{}); ok { |
123 | | - if _, ok := m["Alpha"]; ok { |
124 | | - foundAlpha = true |
125 | | - } |
126 | | - if _, ok := m["Beta"]; ok { |
127 | | - foundBeta = true |
128 | | - } |
129 | | - } |
130 | | - } |
131 | | - assert.True(t, foundAlpha) |
132 | | - assert.True(t, foundBeta) |
| 70 | + root := &cobra.Command{Use: "pipeleak"} |
| 71 | + alpha := &cobra.Command{Use: "alpha", Run: func(cmd *cobra.Command, args []string) {}} |
| 72 | + deepParent := &cobra.Command{Use: "beta"} |
| 73 | + deepChild := &cobra.Command{Use: "deep", Run: func(cmd *cobra.Command, args []string) {}} |
| 74 | + deepParent.AddCommand(deepChild) |
| 75 | + root.AddCommand(alpha) |
| 76 | + root.AddCommand(deepParent) |
| 77 | + |
| 78 | + tmpDir := t.TempDir() |
| 79 | + // Change working directory to module root (src/pipeleak) so relative ../../docs resolves correctly |
| 80 | + wd, _ := os.Getwd() |
| 81 | + rootDir := filepath.Clean(filepath.Join(wd, "..", "..")) |
| 82 | + old := wd |
| 83 | + if err := os.Chdir(rootDir); err != nil { |
| 84 | + t.Fatalf("failed to chdir to root: %v", err) |
| 85 | + } |
| 86 | + defer func() { _ = os.Chdir(old) }() |
| 87 | + |
| 88 | + err := writeMkdocsYaml(root, tmpDir, false) |
| 89 | + assert.NoError(t, err) |
| 90 | + |
| 91 | + data, err := os.ReadFile(filepath.Join(tmpDir, "mkdocs.yml")) |
| 92 | + assert.NoError(t, err) |
| 93 | + |
| 94 | + var parsed map[string]interface{} |
| 95 | + err = yaml.Unmarshal(data, &parsed) |
| 96 | + assert.NoError(t, err) |
| 97 | + |
| 98 | + // Basic keys exist |
| 99 | + assert.Equal(t, "Pipeleak - Pipeline Secrets Scanner", parsed["site_name"]) |
| 100 | + assert.Equal(t, "pipeleak", parsed["docs_dir"]) |
| 101 | + |
| 102 | + // Nav structure assertions |
| 103 | + navAny, ok := parsed["nav"].([]interface{}) |
| 104 | + assert.True(t, ok) |
| 105 | + assert.Equal(t, 4, len(navAny)) // intro, methodology, alpha, beta |
| 106 | + |
| 107 | + // Introduction entry first |
| 108 | + introMap, ok := navAny[0].(map[string]interface{}) |
| 109 | + assert.True(t, ok) |
| 110 | + assert.Contains(t, introMap, "Introduction") |
| 111 | + assert.Equal(t, "/introduction/getting_started/", introMap["Introduction"]) |
| 112 | + |
| 113 | + // Methodology second |
| 114 | + methMap, ok := navAny[1].(map[string]interface{}) |
| 115 | + assert.True(t, ok) |
| 116 | + assert.Contains(t, methMap, "Methodology") |
| 117 | + |
| 118 | + // Command entries appear after methodology |
| 119 | + foundAlpha := false |
| 120 | + foundBeta := false |
| 121 | + for _, item := range navAny[2:] { |
| 122 | + if m, ok := item.(map[string]interface{}); ok { |
| 123 | + if _, ok := m["Alpha"]; ok { |
| 124 | + foundAlpha = true |
| 125 | + } |
| 126 | + if _, ok := m["Beta"]; ok { |
| 127 | + foundBeta = true |
| 128 | + } |
| 129 | + } |
| 130 | + } |
| 131 | + assert.True(t, foundAlpha) |
| 132 | + assert.True(t, foundBeta) |
133 | 133 | } |
134 | 134 |
|
135 | 135 | // writeMkdocsYaml with GithubPages should prefix nav paths. |
136 | 136 | func TestWriteMkdocsYaml_GithubPagesPrefix(t *testing.T) { |
137 | | - root := &cobra.Command{Use: "pipeleak"} |
138 | | - root.AddCommand(&cobra.Command{Use: "alpha", Run: func(cmd *cobra.Command, args []string) {}}) |
139 | | - |
140 | | - tmpDir := t.TempDir() |
141 | | - wd, _ := os.Getwd() |
142 | | - rootDir := filepath.Clean(filepath.Join(wd, "..", "..")) |
143 | | - old := wd |
144 | | - if err := os.Chdir(rootDir); err != nil { |
145 | | - t.Fatalf("failed to chdir to root: %v", err) |
146 | | - } |
147 | | - defer func() { _ = os.Chdir(old) }() |
148 | | - |
149 | | - err := writeMkdocsYaml(root, tmpDir, true) |
150 | | - assert.NoError(t, err) |
151 | | - data, err := os.ReadFile(filepath.Join(tmpDir, "mkdocs.yml")) |
152 | | - assert.NoError(t, err) |
153 | | - var parsed map[string]interface{} |
154 | | - err = yaml.Unmarshal(data, &parsed) |
155 | | - assert.NoError(t, err) |
156 | | - navAny := parsed["nav"].([]interface{}) |
157 | | - introMap := navAny[0].(map[string]interface{}) |
158 | | - assert.Equal(t, "/pipeleak/introduction/getting_started/", introMap["Introduction"]) |
| 137 | + root := &cobra.Command{Use: "pipeleak"} |
| 138 | + root.AddCommand(&cobra.Command{Use: "alpha", Run: func(cmd *cobra.Command, args []string) {}}) |
| 139 | + |
| 140 | + tmpDir := t.TempDir() |
| 141 | + wd, _ := os.Getwd() |
| 142 | + rootDir := filepath.Clean(filepath.Join(wd, "..", "..")) |
| 143 | + old := wd |
| 144 | + if err := os.Chdir(rootDir); err != nil { |
| 145 | + t.Fatalf("failed to chdir to root: %v", err) |
| 146 | + } |
| 147 | + defer func() { _ = os.Chdir(old) }() |
| 148 | + |
| 149 | + err := writeMkdocsYaml(root, tmpDir, true) |
| 150 | + assert.NoError(t, err) |
| 151 | + data, err := os.ReadFile(filepath.Join(tmpDir, "mkdocs.yml")) |
| 152 | + assert.NoError(t, err) |
| 153 | + var parsed map[string]interface{} |
| 154 | + err = yaml.Unmarshal(data, &parsed) |
| 155 | + assert.NoError(t, err) |
| 156 | + navAny := parsed["nav"].([]interface{}) |
| 157 | + introMap := navAny[0].(map[string]interface{}) |
| 158 | + assert.Equal(t, "/pipeleak/introduction/getting_started/", introMap["Introduction"]) |
159 | 159 | } |
0 commit comments