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