1<?php
2
3namespace dokuwiki\plugin\simplenavi\test;
4
5use dokuwiki\TreeBuilder\PageTreeBuilder;
6use DokuWikiTest;
7
8/**
9 * General tests for the simplenavi plugin
10 *
11 * @author  Michael Große <grosse@cosmocode.de>
12 *
13 * @group plugin_simplenavi
14 * @group plugins
15 */
16class SimplenaviTest extends DokuWikiTest
17{
18
19    protected $pluginsEnabled = array('simplenavi');
20
21    public function setUp(): void
22    {
23        global $conf;
24
25        parent::setUp();
26        saveWikiText('sidebar', '{{simplenavi>}}', 'create test sidebar');
27
28        $conf['hidepages'] = ':hidden(:|$)';
29
30        $pages = [
31            ['foo', 'Foo Page'],
32            ['simplenavi', 'Self Start'],
33            ['namespace1:start', 'ZZZ Namespace 1 Start'],
34            ['namespace2:foo', 'Namespace 2 Foo'],
35            ['namespace2', 'Namespace 2 Start'],
36            ['namespace12:foo', 'Namespace 12 Foo'],
37            ['namespace12:start', 'Namespace 12 Start'],
38            ['namespace123:namespace123', 'AAA Namespace 123 Start'],
39            ['namespace123:foo', 'Namespace 123 Foo'],
40            ['namespace123:hidden', 'A hidden page'],
41            ['namespace123:deep:start', 'Namespace 123 Deep Start'],
42            ['namespace123:deep:foo', 'Namespace 123 Deep Foo'],
43            ['namespace21:foo', 'Namespace 21 Foo'],
44            ['namespace21:start', 'Namespace 21 Start'],
45        ];
46
47        foreach ($pages as $page) {
48            saveWikiText('simplenavi:' . $page[0], '====== ' . $page[1] . ' ======', 'create test page');
49        }
50
51    }
52
53    public function dataProvider()
54    {
55
56        yield [
57            'set' => 'by ID, all branches closed',
58            'sort' => 'id',
59            'usetitle' => false,
60            'home' => false,
61            'current' => 'simplenavi:page',
62            'expect' => [
63                '+simplenavi:foo',
64                '+simplenavi:namespace1:start',
65                '+simplenavi:namespace12:start',
66                '+simplenavi:namespace123:namespace123',
67                '+simplenavi:namespace2',
68                '+simplenavi:namespace21:start',
69            ]
70        ];
71
72        yield [
73            'set' => 'by ID, branch open',
74            'sort' => 'id',
75            'usetitle' => false,
76            'home' => false,
77            'current' => 'simplenavi:namespace123:deep:foo',
78            'expect' => [
79                '+simplenavi:foo',
80                '+simplenavi:namespace1:start',
81                '+simplenavi:namespace12:start',
82                '+simplenavi:namespace123:namespace123',
83                '++simplenavi:namespace123:deep:start',
84                '+++simplenavi:namespace123:deep:foo',
85                '++simplenavi:namespace123:foo',
86                '+simplenavi:namespace2',
87                '+simplenavi:namespace21:start',
88            ]
89        ];
90
91
92        yield [
93            'set' => 'by Title, Natural Search, all branches closed',
94            'sort' => 'title',
95            'usetitle' => true,
96            'home' => false,
97            'current' => 'simplenavi:page',
98            'expect' => [
99                '+simplenavi:namespace123:namespace123',
100                '+simplenavi:foo',
101                '+simplenavi:namespace2',
102                '+simplenavi:namespace12:start',
103                '+simplenavi:namespace21:start',
104                '+simplenavi:namespace1:start',
105            ]
106        ];
107
108        yield [
109            'set' => 'by Title, Natural Sort, branch open',
110            'sort' => 'title',
111            'usetitle' => true,
112            'home' => false,
113            'current' => 'simplenavi:namespace123:deep:foo',
114            'expect' => [
115                '+simplenavi:namespace123:namespace123',
116                '++simplenavi:namespace123:deep:start',
117                '+++simplenavi:namespace123:deep:foo',
118                '++simplenavi:namespace123:foo',
119                '+simplenavi:foo',
120                '+simplenavi:namespace2',
121                '+simplenavi:namespace12:start',
122                '+simplenavi:namespace21:start',
123                '+simplenavi:namespace1:start',
124            ]
125        ];
126
127        yield [
128            'set' => 'by Title, Natural Sort, NS first, branch open',
129            'sort' => 'ns_title',
130            'usetitle' => true,
131            'home' => false,
132            'current' => 'simplenavi:namespace123:deep:foo',
133            'expect' => [
134                '+simplenavi:namespace123:namespace123',
135                '++simplenavi:namespace123:deep:start',
136                '+++simplenavi:namespace123:deep:foo',
137                '++simplenavi:namespace123:foo',
138                '+simplenavi:namespace2',
139                '+simplenavi:namespace12:start',
140                '+simplenavi:namespace21:start',
141                '+simplenavi:namespace1:start',
142                '+simplenavi:foo',
143            ]
144        ];
145
146        yield [
147            'set' => 'by ID, branch open with home level',
148            'sort' => 'id',
149            'usetitle' => false,
150            'home' => true,
151            'current' => 'simplenavi:namespace123:deep:foo',
152            'expect' => [
153                '+simplenavi:simplenavi',
154                '++simplenavi:foo',
155                '++simplenavi:namespace1:start',
156                '++simplenavi:namespace12:start',
157                '++simplenavi:namespace123:namespace123',
158                '+++simplenavi:namespace123:deep:start',
159                '++++simplenavi:namespace123:deep:foo',
160                '+++simplenavi:namespace123:foo',
161                '++simplenavi:namespace2',
162                '++simplenavi:namespace21:start',
163            ]
164        ];
165    }
166
167    /**
168     * @dataProvider dataProvider
169     */
170    public function testSorting($set, $sort, $usetitle, $home, $current, $expect)
171    {
172        $simpleNavi = new \syntax_plugin_simplenavi();
173
174        $simpleNavi->initState('simplenavi', $current, $usetitle, $sort, $home);
175
176        /** @var PageTreeBuilder $tree */
177        $tree = $this->callInaccessibleMethod($simpleNavi, 'getTree', []);
178
179
180        $this->assertSame(join("\n", $expect), (string) $tree, $set);
181    }
182
183    /**
184     * Data provider for isParent test
185     */
186    public function isParentDataProvider(): array
187    {
188        return [
189            // Test cases where parent is a parent of child
190            'parent of deep child' => [true, 'namespace1:namespace2:page', 'namespace1'],
191            'direct parent' => [true, 'namespace1:namespace2:page', 'namespace1:namespace2'],
192            'parent of page' => [true, 'namespace1:page', 'namespace1'],
193
194            // Test cases where parent is not a parent of child
195            'different namespace' => [false, 'namespace1:page', 'namespace2'],
196            'sibling namespace' => [false, 'namespace1:namespace2:page', 'namespace1:namespace3'],
197
198            // Test edge cases
199            'empty parent' => [true, 'page', ''], // Empty parent is parent of all
200            'self as parent' => [true, 'page', 'page'], // Page is parent of itself
201        ];
202    }
203
204    /**
205     * Test the isParent method
206     * @dataProvider isParentDataProvider
207     */
208    public function testIsParent(bool $expected, string $child, string $parent): void
209    {
210        $simpleNavi = new \syntax_plugin_simplenavi();
211        $result = $this->callInaccessibleMethod($simpleNavi, 'isParent', [$child, $parent]);
212        $this->assertSame($expected, $result);
213    }
214
215}
216
217
218
219