xref: /plugin/dw2pdf/_test/ExportFeedbackTest.php (revision 40a07da2a0a1fe205d2fb62c8cd8b8968e580efa)
1<?php
2
3namespace dokuwiki\plugin\dw2pdf\test;
4
5use dokuwiki\plugin\dw2pdf\src\BookCreatorLiveSelectionCollector;
6use dokuwiki\plugin\dw2pdf\src\Cache;
7use dokuwiki\plugin\dw2pdf\src\Config;
8use dokuwiki\plugin\dw2pdf\src\ExportException;
9use dokuwiki\plugin\dw2pdf\src\PdfExportService;
10use dokuwiki\test\mock\AuthPlugin;
11use DokuWikiTest;
12
13/**
14 * Tests the feedback given when an export yields no usable pages
15 *
16 * @group plugin_dw2pdf
17 * @group plugins
18 */
19class ExportFeedbackTest extends DokuWikiTest
20{
21    /** @var string[] Plugins to enable for these tests */
22    protected $pluginsEnabled = ['dw2pdf'];
23
24    /** @var array|null Saved ACL rules to restore after each test */
25    protected $oldAuthAcl;
26
27    public function setUp(): void
28    {
29        parent::setUp();
30        $_REQUEST = [];
31
32        global $AUTH_ACL, $auth;
33        $this->oldAuthAcl = $AUTH_ACL;
34        $auth = new AuthPlugin();
35    }
36
37    public function tearDown(): void
38    {
39        global $AUTH_ACL;
40        $AUTH_ACL = $this->oldAuthAcl;
41        parent::tearDown();
42    }
43
44    /**
45     * Deny read access to everybody
46     */
47    protected function denyAll(): void
48    {
49        global $conf, $AUTH_ACL;
50        $conf['useacl'] = 1;
51        $AUTH_ACL = ['*    @ALL    0'];
52    }
53
54    /**
55     * When every selected page is unreadable, they are dropped from the export but remembered.
56     */
57    public function testForbiddenPagesArePartitioned(): void
58    {
59        global $INPUT;
60        $pageA = 'playground:secret:a';
61        $pageB = 'playground:secret:b';
62        saveWikiText($pageA, 'A', 'create');
63        saveWikiText($pageB, 'B', 'create');
64
65        $this->denyAll();
66        $INPUT->set('selection', json_encode([$pageA, $pageB]));
67
68        $collector = new BookCreatorLiveSelectionCollector(new Config());
69        $this->assertSame([], $collector->getPages());
70        $this->assertSame([$pageA, $pageB], $collector->getSkippedPages());
71    }
72
73    /**
74     * Readable pages are kept while forbidden ones are skipped (always-skip behavior).
75     */
76    public function testMixedAccessKeepsReadablePages(): void
77    {
78        global $INPUT, $conf, $AUTH_ACL;
79        $readable = 'playground:public:a';
80        $secret = 'playground:secret:b';
81        saveWikiText($readable, 'A', 'create');
82        saveWikiText($secret, 'B', 'create');
83
84        $conf['useacl'] = 1;
85        $AUTH_ACL = [
86            '*                    @ALL    8',
87            'playground:secret:*  @ALL    0',
88        ];
89        $INPUT->set('selection', json_encode([$readable, $secret]));
90
91        $collector = new BookCreatorLiveSelectionCollector(new Config());
92        $this->assertSame([$readable], $collector->getPages());
93        $this->assertSame([$secret], $collector->getSkippedPages());
94    }
95
96    /**
97     * An export where every page is forbidden reports only how many pages were skipped.
98     */
99    public function testServiceThrowsForbiddenWhenAllSkipped(): void
100    {
101        $pageA = 'playground:secret:a';
102        saveWikiText($pageA, 'A', 'create');
103        $this->denyAll();
104
105        $service = $this->makeService([$pageA]);
106
107        try {
108            $service->getDebugHtml();
109            $this->fail('Expected ExportException was not thrown');
110        } catch (ExportException $e) {
111            $this->assertSame('forbidden', $e->getMessage());
112            $this->assertSame([], $e->getArgs(), 'No details about the skipped pages should be exposed');
113        }
114    }
115
116    /**
117     * An export with no selection at all reports an empty selection.
118     */
119    public function testServiceThrowsEmptyWhenNothingSelected(): void
120    {
121        $service = $this->makeService([]);
122
123        $this->expectException(ExportException::class);
124        $this->expectExceptionMessage('empty');
125        $service->getDebugHtml();
126    }
127
128    /**
129     * Build a debug PdfExportService for a live book selection.
130     *
131     * @param string[] $selection Page ids to export
132     * @return PdfExportService
133     */
134    protected function makeService(array $selection): PdfExportService
135    {
136        $config = new Config(['debug' => 1, 'liveselection' => json_encode($selection)]);
137        $collector = new BookCreatorLiveSelectionCollector($config);
138        $cache = new Cache($config, $collector);
139        return new PdfExportService($config, $collector, $cache, 'Contents', 'tester');
140    }
141}
142