xref: /dokuwiki/_test/tests/Remote/ApiCoreTest.php (revision d1f06eb4f0e4febc5434c97e319fce6d0253e533)
153585189SAndreas Gohr<?php
253585189SAndreas Gohr
353585189SAndreas Gohrnamespace dokuwiki\test\Remote;
453585189SAndreas Gohr
553585189SAndreas Gohruse dokuwiki\Extension\Event;
6*d1f06eb4SAndreas Gohruse dokuwiki\Remote\AccessDeniedException;
753585189SAndreas Gohruse dokuwiki\Remote\Api;
853585189SAndreas Gohruse dokuwiki\Remote\ApiCore;
9*d1f06eb4SAndreas Gohruse dokuwiki\Remote\RemoteException;
1053585189SAndreas Gohruse dokuwiki\test\mock\AuthDeletePlugin;
1153585189SAndreas Gohruse dokuwiki\test\mock\AuthPlugin;
1253585189SAndreas Gohr
13*d1f06eb4SAndreas Gohr
1453585189SAndreas Gohr/**
1553585189SAndreas Gohr * Class remoteapicore_test
1653585189SAndreas Gohr */
1753585189SAndreas Gohrclass ApiCoreTest extends \DokuWikiTest
1853585189SAndreas Gohr{
1953585189SAndreas Gohr
2053585189SAndreas Gohr    protected $userinfo;
2153585189SAndreas Gohr    protected $oldAuthAcl;
2253585189SAndreas Gohr    /** @var  Api */
2353585189SAndreas Gohr    protected $remote;
2453585189SAndreas Gohr
2553585189SAndreas Gohr    public function setUp(): void
2653585189SAndreas Gohr    {
2753585189SAndreas Gohr        // we need a clean setup before each single test:
2853585189SAndreas Gohr        \DokuWikiTest::setUpBeforeClass();
2953585189SAndreas Gohr
3053585189SAndreas Gohr        parent::setUp();
3153585189SAndreas Gohr        global $conf;
3253585189SAndreas Gohr        global $USERINFO;
3353585189SAndreas Gohr        global $AUTH_ACL;
3453585189SAndreas Gohr        global $auth;
3553585189SAndreas Gohr        $this->oldAuthAcl = $AUTH_ACL;
3653585189SAndreas Gohr        $this->userinfo = $USERINFO;
3753585189SAndreas Gohr        $auth = new AuthPlugin();
3853585189SAndreas Gohr
3953585189SAndreas Gohr        $conf['remote'] = 1;
4053585189SAndreas Gohr        $conf['remoteuser'] = '@user';
4153585189SAndreas Gohr        $conf['useacl'] = 0;
4253585189SAndreas Gohr
4353585189SAndreas Gohr        $this->remote = new Api();
4453585189SAndreas Gohr    }
4553585189SAndreas Gohr
4653585189SAndreas Gohr    public function tearDown(): void
4753585189SAndreas Gohr    {
4853585189SAndreas Gohr        parent::tearDown();
4953585189SAndreas Gohr
5053585189SAndreas Gohr        global $USERINFO;
5153585189SAndreas Gohr        global $AUTH_ACL;
5253585189SAndreas Gohr
5353585189SAndreas Gohr        $USERINFO = $this->userinfo;
5453585189SAndreas Gohr        $AUTH_ACL = $this->oldAuthAcl;
5553585189SAndreas Gohr    }
5653585189SAndreas Gohr
57*d1f06eb4SAndreas Gohr    /**
58*d1f06eb4SAndreas Gohr     * Do an assertion that converts to JSON inbetween
59*d1f06eb4SAndreas Gohr     *
60*d1f06eb4SAndreas Gohr     * This lets us compare result objects with arrays
61*d1f06eb4SAndreas Gohr     */
62*d1f06eb4SAndreas Gohr    protected function assertEqualResult($expected, $actual, $msg = '')
6353585189SAndreas Gohr    {
64*d1f06eb4SAndreas Gohr        // sort object arrays
65*d1f06eb4SAndreas Gohr        if (is_array($actual) && array_key_exists(0, $actual) && is_object($actual[0])) {
66*d1f06eb4SAndreas Gohr            sort($actual);
67*d1f06eb4SAndreas Gohr            sort($expected);
6853585189SAndreas Gohr        }
6953585189SAndreas Gohr
70*d1f06eb4SAndreas Gohr        $expected = json_decode(json_encode($expected), true);
71*d1f06eb4SAndreas Gohr        $actual = json_decode(json_encode($actual), true);
72*d1f06eb4SAndreas Gohr        $this->assertEquals($expected, $actual, $msg);
7353585189SAndreas Gohr    }
7453585189SAndreas Gohr
75*d1f06eb4SAndreas Gohr    // region info
76*d1f06eb4SAndreas Gohr
77*d1f06eb4SAndreas Gohr    // core.getAPIVersion
78*d1f06eb4SAndreas Gohr    public function testGetAPIVersion()
7953585189SAndreas Gohr    {
80*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
81*d1f06eb4SAndreas Gohr            ApiCore::API_VERSION,
82*d1f06eb4SAndreas Gohr            $this->remote->call('core.getAPIVersion')
83*d1f06eb4SAndreas Gohr        );
84*d1f06eb4SAndreas Gohr    }
85*d1f06eb4SAndreas Gohr
86*d1f06eb4SAndreas Gohr    // core.getWikiVersion
87*d1f06eb4SAndreas Gohr    public function testGetWikiVersion()
88*d1f06eb4SAndreas Gohr    {
89*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
90*d1f06eb4SAndreas Gohr            getVersion(),
91*d1f06eb4SAndreas Gohr            $this->remote->call('core.getWikiVersion')
92*d1f06eb4SAndreas Gohr        );
93*d1f06eb4SAndreas Gohr    }
94*d1f06eb4SAndreas Gohr
95*d1f06eb4SAndreas Gohr    // core.getWikiTitle
96*d1f06eb4SAndreas Gohr    public function testGetWikiTitle()
97*d1f06eb4SAndreas Gohr    {
98*d1f06eb4SAndreas Gohr        global $conf;
99*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
100*d1f06eb4SAndreas Gohr            $conf['title'],
101*d1f06eb4SAndreas Gohr            $this->remote->call('core.getWikiTitle')
102*d1f06eb4SAndreas Gohr        );
103*d1f06eb4SAndreas Gohr    }
104*d1f06eb4SAndreas Gohr
105*d1f06eb4SAndreas Gohr    // core.getWikiTime
106*d1f06eb4SAndreas Gohr    public function testGetWikiTime()
107*d1f06eb4SAndreas Gohr    {
108*d1f06eb4SAndreas Gohr        $this->assertEqualsWithDelta(
109*d1f06eb4SAndreas Gohr            time(),
110*d1f06eb4SAndreas Gohr            $this->remote->call('core.getWikiTime'),
111*d1f06eb4SAndreas Gohr            1 // allow 1 second difference
112*d1f06eb4SAndreas Gohr        );
113*d1f06eb4SAndreas Gohr    }
114*d1f06eb4SAndreas Gohr
115*d1f06eb4SAndreas Gohr    // endregion
116*d1f06eb4SAndreas Gohr
117*d1f06eb4SAndreas Gohr    // region user
118*d1f06eb4SAndreas Gohr
119*d1f06eb4SAndreas Gohr    // core.login
120*d1f06eb4SAndreas Gohr    public function testLogin()
121*d1f06eb4SAndreas Gohr    {
122*d1f06eb4SAndreas Gohr        $this->markTestIncomplete('Missing test for core.login API Call');
123*d1f06eb4SAndreas Gohr    }
124*d1f06eb4SAndreas Gohr
125*d1f06eb4SAndreas Gohr    // core.logoff
126*d1f06eb4SAndreas Gohr    public function testLogoff()
127*d1f06eb4SAndreas Gohr    {
128*d1f06eb4SAndreas Gohr        $this->markTestIncomplete('Missing test for core.logoff API Call');
129*d1f06eb4SAndreas Gohr    }
130*d1f06eb4SAndreas Gohr
131*d1f06eb4SAndreas Gohr    // core.whoAmI
132*d1f06eb4SAndreas Gohr    public function testWhoAmI()
133*d1f06eb4SAndreas Gohr    {
134*d1f06eb4SAndreas Gohr        $this->markTestIncomplete('Missing test for core.whoAmI API Call');
135*d1f06eb4SAndreas Gohr    }
136*d1f06eb4SAndreas Gohr
137*d1f06eb4SAndreas Gohr    // core.aclCheck -> See also ApiCoreAclCheckTest.php
138*d1f06eb4SAndreas Gohr    public function testAclCheck()
139*d1f06eb4SAndreas Gohr    {
140*d1f06eb4SAndreas Gohr        $id = 'aclpage';
141*d1f06eb4SAndreas Gohr
142*d1f06eb4SAndreas Gohr        $this->assertEquals(AUTH_UPLOAD, $this->remote->call('core.aclCheck', ['page' => $id]));
143*d1f06eb4SAndreas Gohr
144*d1f06eb4SAndreas Gohr        global $conf;
145*d1f06eb4SAndreas Gohr        global $AUTH_ACL;
146*d1f06eb4SAndreas Gohr        global $USERINFO;
147*d1f06eb4SAndreas Gohr        $conf['useacl'] = 1;
148*d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'john';
149*d1f06eb4SAndreas Gohr        $USERINFO['grps'] = ['user'];
150*d1f06eb4SAndreas Gohr        $AUTH_ACL = [
151*d1f06eb4SAndreas Gohr            '*                  @ALL           0',
152*d1f06eb4SAndreas Gohr            '*                  @user          2', //edit
153*d1f06eb4SAndreas Gohr        ];
154*d1f06eb4SAndreas Gohr
155*d1f06eb4SAndreas Gohr        $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', ['page' => $id]));
156*d1f06eb4SAndreas Gohr    }
157*d1f06eb4SAndreas Gohr
158*d1f06eb4SAndreas Gohr
159*d1f06eb4SAndreas Gohr    // endregion
160*d1f06eb4SAndreas Gohr
161*d1f06eb4SAndreas Gohr    // region pages
162*d1f06eb4SAndreas Gohr
163*d1f06eb4SAndreas Gohr    // core.listPages
164*d1f06eb4SAndreas Gohr    public function testlistPagesAll()
165*d1f06eb4SAndreas Gohr    {
166*d1f06eb4SAndreas Gohr        // all pages depends on index
167*d1f06eb4SAndreas Gohr        idx_addPage('wiki:syntax');
168*d1f06eb4SAndreas Gohr        idx_addPage('wiki:dokuwiki');
169*d1f06eb4SAndreas Gohr
170*d1f06eb4SAndreas Gohr        $file1 = wikiFN('wiki:syntax');
171*d1f06eb4SAndreas Gohr        $file2 = wikiFN('wiki:dokuwiki');
172*d1f06eb4SAndreas Gohr
17353585189SAndreas Gohr        $expected = [
17453585189SAndreas Gohr            [
175*d1f06eb4SAndreas Gohr                'id' => 'wiki:syntax',
176*d1f06eb4SAndreas Gohr                'title' => 'wiki:syntax',
177*d1f06eb4SAndreas Gohr                'permission' => 8,
17853585189SAndreas Gohr                'size' => filesize($file1),
179*d1f06eb4SAndreas Gohr                'revision' => filemtime($file1),
180*d1f06eb4SAndreas Gohr                'hash' => md5(io_readFile($file1)),
181*d1f06eb4SAndreas Gohr                'author' => '',
18253585189SAndreas Gohr            ],
18353585189SAndreas Gohr            [
184*d1f06eb4SAndreas Gohr                'id' => 'wiki:dokuwiki',
185*d1f06eb4SAndreas Gohr                'title' => 'wiki:dokuwiki',
186*d1f06eb4SAndreas Gohr                'permission' => 8,
18753585189SAndreas Gohr                'size' => filesize($file2),
188*d1f06eb4SAndreas Gohr                'revision' => filemtime($file2),
189*d1f06eb4SAndreas Gohr                'hash' => md5(io_readFile($file2)),
190*d1f06eb4SAndreas Gohr                'author' => '',
19153585189SAndreas Gohr            ]
19253585189SAndreas Gohr        ];
193*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
194*d1f06eb4SAndreas Gohr            $expected,
195*d1f06eb4SAndreas Gohr            $this->remote->call(
196*d1f06eb4SAndreas Gohr                'core.listPages',
19753585189SAndreas Gohr                [
198*d1f06eb4SAndreas Gohr                    'namespace' => '',
19953585189SAndreas Gohr                    'depth' => 0, // 0 for all
200*d1f06eb4SAndreas Gohr                    'hash' => true
20153585189SAndreas Gohr                ]
202*d1f06eb4SAndreas Gohr            )
203*d1f06eb4SAndreas Gohr        );
20453585189SAndreas Gohr    }
20553585189SAndreas Gohr
206*d1f06eb4SAndreas Gohr    // core.listPages
207*d1f06eb4SAndreas Gohr    public function testListPagesNamespace()
208*d1f06eb4SAndreas Gohr    {
209*d1f06eb4SAndreas Gohr        $file1 = wikiFN('wiki:syntax');
210*d1f06eb4SAndreas Gohr        $file2 = wikiFN('wiki:dokuwiki');
211*d1f06eb4SAndreas Gohr        // no indexing needed here
212*d1f06eb4SAndreas Gohr
213*d1f06eb4SAndreas Gohr        global $conf;
214*d1f06eb4SAndreas Gohr        $conf['useheading'] = 1;
215*d1f06eb4SAndreas Gohr
216*d1f06eb4SAndreas Gohr        $expected = [
217*d1f06eb4SAndreas Gohr            [
218*d1f06eb4SAndreas Gohr                'id' => 'wiki:syntax',
219*d1f06eb4SAndreas Gohr                'title' => 'Formatting Syntax',
220*d1f06eb4SAndreas Gohr                'permission' => 8,
221*d1f06eb4SAndreas Gohr                'size' => filesize($file1),
222*d1f06eb4SAndreas Gohr                'revision' => filemtime($file1),
223*d1f06eb4SAndreas Gohr                'hash' => '',
224*d1f06eb4SAndreas Gohr                'author' => '',
225*d1f06eb4SAndreas Gohr            ],
226*d1f06eb4SAndreas Gohr            [
227*d1f06eb4SAndreas Gohr                'id' => 'wiki:dokuwiki',
228*d1f06eb4SAndreas Gohr                'title' => 'DokuWiki',
229*d1f06eb4SAndreas Gohr                'permission' => 8,
230*d1f06eb4SAndreas Gohr                'size' => filesize($file2),
231*d1f06eb4SAndreas Gohr                'revision' => filemtime($file2),
232*d1f06eb4SAndreas Gohr                'hash' => '',
233*d1f06eb4SAndreas Gohr                'author' => '',
234*d1f06eb4SAndreas Gohr            ],
235*d1f06eb4SAndreas Gohr        ];
236*d1f06eb4SAndreas Gohr
237*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
238*d1f06eb4SAndreas Gohr            $expected,
239*d1f06eb4SAndreas Gohr            $this->remote->call(
240*d1f06eb4SAndreas Gohr                'core.listPages',
241*d1f06eb4SAndreas Gohr                [
242*d1f06eb4SAndreas Gohr                    'namespace' => 'wiki:',
243*d1f06eb4SAndreas Gohr                    'depth' => 1,
244*d1f06eb4SAndreas Gohr                ]
245*d1f06eb4SAndreas Gohr            )
246*d1f06eb4SAndreas Gohr        );
247*d1f06eb4SAndreas Gohr    }
248*d1f06eb4SAndreas Gohr
249*d1f06eb4SAndreas Gohr    // core.searchPages
250*d1f06eb4SAndreas Gohr    public function testSearchPages()
25153585189SAndreas Gohr    {
25253585189SAndreas Gohr        $id = 'wiki:syntax';
25353585189SAndreas Gohr        $file = wikiFN($id);
25453585189SAndreas Gohr
25553585189SAndreas Gohr        idx_addPage($id); //full text search depends on index
25653585189SAndreas Gohr        $expected = [
25753585189SAndreas Gohr            [
25853585189SAndreas Gohr                'id' => $id,
25953585189SAndreas Gohr                'score' => 1,
260*d1f06eb4SAndreas Gohr                'revision' => filemtime($file),
261*d1f06eb4SAndreas Gohr                'permission' => 8,
26253585189SAndreas Gohr                'size' => filesize($file),
26353585189SAndreas Gohr                'snippet' => ' a footnote)) by using double parentheses.
26453585189SAndreas Gohr
26553585189SAndreas Gohr===== <strong class="search_hit">Sectioning</strong> =====
26653585189SAndreas Gohr
26753585189SAndreas GohrYou can use up to five different levels of',
268*d1f06eb4SAndreas Gohr                'title' => 'wiki:syntax',
269*d1f06eb4SAndreas Gohr                'author' => '',
270*d1f06eb4SAndreas Gohr                'hash' => '',
27153585189SAndreas Gohr            ]
27253585189SAndreas Gohr        ];
27353585189SAndreas Gohr
274*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
275*d1f06eb4SAndreas Gohr            $expected,
276*d1f06eb4SAndreas Gohr            $this->remote->call(
277*d1f06eb4SAndreas Gohr                'core.searchPages',
27853585189SAndreas Gohr                [
279*d1f06eb4SAndreas Gohr                    'query' => 'Sectioning'
28053585189SAndreas Gohr                ]
281*d1f06eb4SAndreas Gohr            )
282*d1f06eb4SAndreas Gohr        );
283*d1f06eb4SAndreas Gohr    }
284*d1f06eb4SAndreas Gohr
285*d1f06eb4SAndreas Gohr    //core.getRecentPageChanges
286*d1f06eb4SAndreas Gohr    public function testGetRecentPageChanges()
287*d1f06eb4SAndreas Gohr    {
288*d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser';
289*d1f06eb4SAndreas Gohr
290*d1f06eb4SAndreas Gohr        saveWikiText('pageone', 'test', 'test one');
291*d1f06eb4SAndreas Gohr        $rev1 = filemtime(wikiFN('pageone'));
292*d1f06eb4SAndreas Gohr        saveWikiText('pagetwo', 'test', 'test two');
293*d1f06eb4SAndreas Gohr        $rev2 = filemtime(wikiFN('pagetwo'));
29453585189SAndreas Gohr
29553585189SAndreas Gohr        $expected = [
29653585189SAndreas Gohr            [
297*d1f06eb4SAndreas Gohr                'id' => 'pageone',
298*d1f06eb4SAndreas Gohr                'revision' => $rev1,
299*d1f06eb4SAndreas Gohr                'author' => 'testuser',
300*d1f06eb4SAndreas Gohr                'sizechange' => 4,
301*d1f06eb4SAndreas Gohr                'summary' => 'test one',
302*d1f06eb4SAndreas Gohr                'type' => 'C',
303*d1f06eb4SAndreas Gohr                'ip' => clientIP(),
304*d1f06eb4SAndreas Gohr            ],
305*d1f06eb4SAndreas Gohr            [
306*d1f06eb4SAndreas Gohr                'id' => 'pagetwo',
307*d1f06eb4SAndreas Gohr                'revision' => $rev2,
308*d1f06eb4SAndreas Gohr                'author' => 'testuser',
309*d1f06eb4SAndreas Gohr                'sizechange' => 4,
310*d1f06eb4SAndreas Gohr                'summary' => 'test two',
311*d1f06eb4SAndreas Gohr                'type' => 'C',
312*d1f06eb4SAndreas Gohr                'ip' => clientIP(),
31353585189SAndreas Gohr            ]
31453585189SAndreas Gohr        ];
31553585189SAndreas Gohr
316*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
317*d1f06eb4SAndreas Gohr            $expected,
318*d1f06eb4SAndreas Gohr            $this->remote->call(
319*d1f06eb4SAndreas Gohr                'core.getRecentPageChanges',
32053585189SAndreas Gohr                [
321*d1f06eb4SAndreas Gohr                    'timestamp' => 0 // all recent changes
32253585189SAndreas Gohr                ]
323*d1f06eb4SAndreas Gohr            )
324*d1f06eb4SAndreas Gohr        );
32553585189SAndreas Gohr    }
32653585189SAndreas Gohr
327*d1f06eb4SAndreas Gohr    // core.getPage
32853585189SAndreas Gohr    public function testGetPage()
32953585189SAndreas Gohr    {
33053585189SAndreas Gohr        $id = 'pageversion';
33153585189SAndreas Gohr        $file = wikiFN($id);
33253585189SAndreas Gohr
33353585189SAndreas Gohr        saveWikiText($id, 'first version', 'first');
33453585189SAndreas Gohr        $rev1 = filemtime($file);
33553585189SAndreas Gohr        clearstatcache(false, $file);
33653585189SAndreas Gohr        $this->waitForTick(true);
33753585189SAndreas Gohr        saveWikiText($id, 'second version', 'second');
33853585189SAndreas Gohr        $rev2 = filemtime($file);
33953585189SAndreas Gohr
340*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
341*d1f06eb4SAndreas Gohr            'second version',
342*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => $id, 'rev' => 0]),
343*d1f06eb4SAndreas Gohr            'no revision given -> current'
344*d1f06eb4SAndreas Gohr        );
34553585189SAndreas Gohr
346*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
347*d1f06eb4SAndreas Gohr            'first version',
348*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => $id, 'rev' => $rev1]),
349*d1f06eb4SAndreas Gohr            '1st revision given'
350*d1f06eb4SAndreas Gohr        );
35153585189SAndreas Gohr
352*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
353*d1f06eb4SAndreas Gohr            'second version',
354*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => $id, 'rev' => $rev2]),
355*d1f06eb4SAndreas Gohr            '2nd revision given'
356*d1f06eb4SAndreas Gohr        );
35753585189SAndreas Gohr
358*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
359*d1f06eb4SAndreas Gohr            '',
360*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => $id, 'rev' => 1234]),
361*d1f06eb4SAndreas Gohr            'Non existing revision given'
362*d1f06eb4SAndreas Gohr        );
36353585189SAndreas Gohr
364*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
365*d1f06eb4SAndreas Gohr            '',
366*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => 'foobar', 'rev' => 1234]),
367*d1f06eb4SAndreas Gohr            'Non existing page given'
368*d1f06eb4SAndreas Gohr        );
36953585189SAndreas Gohr    }
37053585189SAndreas Gohr
371*d1f06eb4SAndreas Gohr    //core.getPageHTML
37253585189SAndreas Gohr    public function testGetPageHTMLVersion()
37353585189SAndreas Gohr    {
37453585189SAndreas Gohr        $id = 'htmltest';
37553585189SAndreas Gohr        $file = wikiFN($id);
37653585189SAndreas Gohr
37753585189SAndreas Gohr        $content1 = "====Title====\nText";
37853585189SAndreas Gohr        $html1 = "\n<h3 class=\"sectionedit1\" id=\"title\">Title</h3>\n<div class=\"level3\">\n\n<p>\nText\n</p>\n\n</div>\n";
37953585189SAndreas Gohr        $content2 = "====Foobar====\nText Bamm";
38053585189SAndreas Gohr        $html2 = "\n<h3 class=\"sectionedit1\" id=\"foobar\">Foobar</h3>\n<div class=\"level3\">\n\n<p>\nText Bamm\n</p>\n\n</div>\n";
38153585189SAndreas Gohr
38253585189SAndreas Gohr        saveWikiText($id, $content1, 'first');
38353585189SAndreas Gohr        $rev1 = filemtime($file);
38453585189SAndreas Gohr        clearstatcache(false, $file);
38553585189SAndreas Gohr        $this->waitForTick(true);
38653585189SAndreas Gohr        saveWikiText($id, $content2, 'second');
38753585189SAndreas Gohr        $rev2 = filemtime($file);
38853585189SAndreas Gohr
389*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
390*d1f06eb4SAndreas Gohr            $html2,
391*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => 0]),
392*d1f06eb4SAndreas Gohr            'no revision given -> current'
393*d1f06eb4SAndreas Gohr        );
39453585189SAndreas Gohr
395*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
396*d1f06eb4SAndreas Gohr            $html1,
397*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => $rev1]),
398*d1f06eb4SAndreas Gohr            '1st revision given'
399*d1f06eb4SAndreas Gohr        );
40053585189SAndreas Gohr
401*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
402*d1f06eb4SAndreas Gohr            $html2,
403*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => $rev2]),
404*d1f06eb4SAndreas Gohr            '2nd revision given'
405*d1f06eb4SAndreas Gohr        );
40653585189SAndreas Gohr
407*d1f06eb4SAndreas Gohr        $e = null;
408*d1f06eb4SAndreas Gohr        try {
409*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => 1234]);
410*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
411*d1f06eb4SAndreas Gohr        }
412*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
413*d1f06eb4SAndreas Gohr        $this->assertEquals(121, $e->getCode(), 'Non existing revision given');
41453585189SAndreas Gohr
415*d1f06eb4SAndreas Gohr        $e = null;
416*d1f06eb4SAndreas Gohr        try {
417*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => 'foobar', 'rev' => 1234]);
418*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
419*d1f06eb4SAndreas Gohr        }
420*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
421*d1f06eb4SAndreas Gohr        $this->assertEquals(121, $e->getCode(), 'Non existing page given');
42253585189SAndreas Gohr    }
42353585189SAndreas Gohr
424*d1f06eb4SAndreas Gohr    //core.getPageInfo
42553585189SAndreas Gohr    public function testGetPageInfo()
42653585189SAndreas Gohr    {
42753585189SAndreas Gohr        $id = 'pageinfo';
42853585189SAndreas Gohr        $file = wikiFN($id);
42953585189SAndreas Gohr
430*d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser';
43153585189SAndreas Gohr
43253585189SAndreas Gohr        saveWikiText($id, 'first version', 'first');
43353585189SAndreas Gohr        $rev1 = filemtime($file);
43453585189SAndreas Gohr        clearstatcache(false, $file);
43553585189SAndreas Gohr        $this->waitForTick(true);
43653585189SAndreas Gohr        saveWikiText($id, 'second version', 'second');
43753585189SAndreas Gohr        $rev2 = filemtime($file);
43853585189SAndreas Gohr
43953585189SAndreas Gohr        $expected = [
440*d1f06eb4SAndreas Gohr            'id' => $id,
441*d1f06eb4SAndreas Gohr            'revision' => $rev2,
442*d1f06eb4SAndreas Gohr            'author' => 'testuser',
443*d1f06eb4SAndreas Gohr            'hash' => md5(io_readFile($file)),
444*d1f06eb4SAndreas Gohr            'title' => $id,
445*d1f06eb4SAndreas Gohr            'size' => filesize($file),
446*d1f06eb4SAndreas Gohr            'permission' => 8,
44753585189SAndreas Gohr        ];
448*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
449*d1f06eb4SAndreas Gohr            $expected,
450*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => 0, 'hash' => true, 'author' => true]),
451*d1f06eb4SAndreas Gohr            'no revision given -> current'
452*d1f06eb4SAndreas Gohr        );
45353585189SAndreas Gohr
45453585189SAndreas Gohr        $expected = [
455*d1f06eb4SAndreas Gohr            'id' => $id,
456*d1f06eb4SAndreas Gohr            'revision' => $rev1,
457*d1f06eb4SAndreas Gohr            'author' => '',
458*d1f06eb4SAndreas Gohr            'hash' => '',
459*d1f06eb4SAndreas Gohr            'title' => $id,
460*d1f06eb4SAndreas Gohr            'size' => filesize(wikiFN($id, $rev1)),
461*d1f06eb4SAndreas Gohr            'permission' => 8,
46253585189SAndreas Gohr        ];
463*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
464*d1f06eb4SAndreas Gohr            $expected,
465*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => $rev1]),
466*d1f06eb4SAndreas Gohr            '1st revision given'
467*d1f06eb4SAndreas Gohr        );
46853585189SAndreas Gohr
46953585189SAndreas Gohr        $expected = [
470*d1f06eb4SAndreas Gohr            'id' => $id,
471*d1f06eb4SAndreas Gohr            'revision' => $rev2,
472*d1f06eb4SAndreas Gohr            'author' => '',
473*d1f06eb4SAndreas Gohr            'hash' => '',
474*d1f06eb4SAndreas Gohr            'title' => $id,
475*d1f06eb4SAndreas Gohr            'size' => filesize(wikiFN($id, $rev2)),
476*d1f06eb4SAndreas Gohr            'permission' => 8,
47753585189SAndreas Gohr        ];
478*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
479*d1f06eb4SAndreas Gohr            $expected,
480*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => $rev2]),
481*d1f06eb4SAndreas Gohr            '2nd revision given'
482*d1f06eb4SAndreas Gohr        );
483*d1f06eb4SAndreas Gohr
484*d1f06eb4SAndreas Gohr        $e = null;
485*d1f06eb4SAndreas Gohr        try {
486*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => 1234]);
487*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
488*d1f06eb4SAndreas Gohr        }
489*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
490*d1f06eb4SAndreas Gohr        $this->assertEquals(121, $e->getCode(), 'Non existing revision given');
491*d1f06eb4SAndreas Gohr
492*d1f06eb4SAndreas Gohr        $e = null;
493*d1f06eb4SAndreas Gohr        try {
494*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => 'foobar', 'rev' => 1234]);
495*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
496*d1f06eb4SAndreas Gohr        }
497*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
498*d1f06eb4SAndreas Gohr        $this->assertEquals(121, $e->getCode(), 'Non existing page given');
49953585189SAndreas Gohr    }
50053585189SAndreas Gohr
501*d1f06eb4SAndreas Gohr    //core.getPageHistory
502*d1f06eb4SAndreas Gohr    public function testGetPageHistory()
50353585189SAndreas Gohr    {
50453585189SAndreas Gohr        global $conf;
50553585189SAndreas Gohr
50653585189SAndreas Gohr        $id = 'revpage';
50753585189SAndreas Gohr        $file = wikiFN($id);
50853585189SAndreas Gohr
50953585189SAndreas Gohr        $rev = [];
51053585189SAndreas Gohr        for ($i = 0; $i < 6; $i++) {
51153585189SAndreas Gohr            $this->waitForTick();
51253585189SAndreas Gohr            saveWikiText($id, "rev$i", "rev$i");
51353585189SAndreas Gohr            clearstatcache(false, $file);
51453585189SAndreas Gohr            $rev[$i] = filemtime($file);
51553585189SAndreas Gohr        }
51653585189SAndreas Gohr
517*d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => 0];
518*d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
519*d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
52053585189SAndreas Gohr        $this->assertEquals(6, count($versions));
521*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[5], $versions[0]['revision']);
522*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[4], $versions[1]['revision']);
523*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[3], $versions[2]['revision']);
524*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[2], $versions[3]['revision']);
525*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[1], $versions[4]['revision']);
526*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[0], $versions[5]['revision']);
52753585189SAndreas Gohr
528*d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => 1]; // offset 1
529*d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
530*d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
53153585189SAndreas Gohr        $this->assertEquals(5, count($versions));
532*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[4], $versions[0]['revision']);
533*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[3], $versions[1]['revision']);
534*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[2], $versions[2]['revision']);
535*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[1], $versions[3]['revision']);
536*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[0], $versions[4]['revision']);
53753585189SAndreas Gohr
53853585189SAndreas Gohr        $conf['recent'] = 3; //set number of results per page
53953585189SAndreas Gohr
540*d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => 0]; // first page
541*d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
542*d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
54353585189SAndreas Gohr        $this->assertEquals(3, count($versions));
544*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[5], $versions[0]['revision']);
545*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[4], $versions[1]['revision']);
546*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[3], $versions[2]['revision']);
54753585189SAndreas Gohr
548*d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => $conf['recent']]; // second page
549*d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
550*d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
55153585189SAndreas Gohr        $this->assertEquals(3, count($versions));
552*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[2], $versions[0]['revision']);
553*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[1], $versions[1]['revision']);
554*d1f06eb4SAndreas Gohr        $this->assertEquals($rev[0], $versions[2]['revision']);
55553585189SAndreas Gohr
556*d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => $conf['recent'] * 2]; // third page
557*d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
558*d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
55953585189SAndreas Gohr        $this->assertEquals(0, count($versions));
56053585189SAndreas Gohr    }
56153585189SAndreas Gohr
562*d1f06eb4SAndreas Gohr    //core.getPageLinks
563*d1f06eb4SAndreas Gohr    public function testGetPageLinks()
56453585189SAndreas Gohr    {
56553585189SAndreas Gohr        $localdoku = [
56653585189SAndreas Gohr            'type' => 'local',
56753585189SAndreas Gohr            'page' => 'DokuWiki',
56853585189SAndreas Gohr            'href' => DOKU_BASE . DOKU_SCRIPT . '?id=DokuWiki'
56953585189SAndreas Gohr        ];
570*d1f06eb4SAndreas Gohr        $expected = [
57153585189SAndreas Gohr            $localdoku,
57253585189SAndreas Gohr            [
57353585189SAndreas Gohr                'type' => 'extern',
57453585189SAndreas Gohr                'page' => 'http://www.freelists.org',
57553585189SAndreas Gohr                'href' => 'http://www.freelists.org'
57653585189SAndreas Gohr            ],
57753585189SAndreas Gohr            [
578*d1f06eb4SAndreas Gohr                'type' => 'interwiki',
579*d1f06eb4SAndreas Gohr                'page' => 'rfc>1855',
58053585189SAndreas Gohr                'href' => 'https://tools.ietf.org/html/rfc1855'
58153585189SAndreas Gohr            ],
58253585189SAndreas Gohr            [
58353585189SAndreas Gohr                'type' => 'extern',
58453585189SAndreas Gohr                'page' => 'http://www.catb.org/~esr/faqs/smart-questions.html',
58553585189SAndreas Gohr                'href' => 'http://www.catb.org/~esr/faqs/smart-questions.html'
58653585189SAndreas Gohr            ],
58753585189SAndreas Gohr            $localdoku,
58853585189SAndreas Gohr            $localdoku
58953585189SAndreas Gohr        ];
590*d1f06eb4SAndreas Gohr
591*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
592*d1f06eb4SAndreas Gohr            $expected,
593*d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageLinks', ['page' => 'mailinglist'])
594*d1f06eb4SAndreas Gohr        );
595*d1f06eb4SAndreas Gohr
596*d1f06eb4SAndreas Gohr        $this->expectExceptionCode(121);
597*d1f06eb4SAndreas Gohr        $this->remote->call('core.getPageLinks', ['page' => 'foobar']);
59853585189SAndreas Gohr    }
59953585189SAndreas Gohr
600*d1f06eb4SAndreas Gohr    //core.getPageBackLinks
601*d1f06eb4SAndreas Gohr    public function testGetPageBackLinks()
602*d1f06eb4SAndreas Gohr    {
603*d1f06eb4SAndreas Gohr        saveWikiText('linky', '[[wiki:syntax]]', 'test');
604*d1f06eb4SAndreas Gohr        // backlinks need index
605*d1f06eb4SAndreas Gohr        idx_addPage('wiki:syntax');
606*d1f06eb4SAndreas Gohr        idx_addPage('linky');
607*d1f06eb4SAndreas Gohr
608*d1f06eb4SAndreas Gohr        $result = $this->remote->call('core.getPageBackLinks', ['page' => 'wiki:syntax']);
609*d1f06eb4SAndreas Gohr        $this->assertTrue(count($result) > 0);
610*d1f06eb4SAndreas Gohr        $this->assertEqualResult(ft_backlinks('wiki:syntax'), $result);
611*d1f06eb4SAndreas Gohr
612*d1f06eb4SAndreas Gohr        $this->assertEquals([], $this->remote->call('core.getPageBackLinks', ['page' => 'foobar']));
613*d1f06eb4SAndreas Gohr    }
614*d1f06eb4SAndreas Gohr
615*d1f06eb4SAndreas Gohr    //core.lockPages
616*d1f06eb4SAndreas Gohr    public function testLockPages()
617*d1f06eb4SAndreas Gohr    {
618*d1f06eb4SAndreas Gohr        // lock a first set of pages
619*d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser1';
620*d1f06eb4SAndreas Gohr        $tolock = ['wiki:dokuwiki', 'nonexisting'];
621*d1f06eb4SAndreas Gohr        $this->assertEquals(
622*d1f06eb4SAndreas Gohr            $tolock,
623*d1f06eb4SAndreas Gohr            $this->remote->call('core.lockPages', ['pages' => $tolock]),
624*d1f06eb4SAndreas Gohr            'all pages should lock'
625*d1f06eb4SAndreas Gohr        );
626*d1f06eb4SAndreas Gohr
627*d1f06eb4SAndreas Gohr        // now we're someone else
628*d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser2';
629*d1f06eb4SAndreas Gohr        $tolock = ['wiki:dokuwiki', 'nonexisting', 'wiki:syntax', 'another'];
630*d1f06eb4SAndreas Gohr        $expected = ['wiki:syntax', 'another'];
631*d1f06eb4SAndreas Gohr        $this->assertEquals(
632*d1f06eb4SAndreas Gohr            $expected,
633*d1f06eb4SAndreas Gohr            $this->remote->call('core.lockPages', ['pages' => $tolock]),
634*d1f06eb4SAndreas Gohr            'only half the pages should lock'
635*d1f06eb4SAndreas Gohr        );
636*d1f06eb4SAndreas Gohr    }
637*d1f06eb4SAndreas Gohr
638*d1f06eb4SAndreas Gohr    // core.unlockPages
639*d1f06eb4SAndreas Gohr    public function testUnlockPages()
640*d1f06eb4SAndreas Gohr    {
641*d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser1';
642*d1f06eb4SAndreas Gohr        lock('wiki:dokuwiki');
643*d1f06eb4SAndreas Gohr        lock('nonexisting');
644*d1f06eb4SAndreas Gohr
645*d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser2';
646*d1f06eb4SAndreas Gohr        lock('wiki:syntax');
647*d1f06eb4SAndreas Gohr        lock('another');
648*d1f06eb4SAndreas Gohr
649*d1f06eb4SAndreas Gohr        $tounlock = ['wiki:dokuwiki', 'nonexisting', 'wiki:syntax', 'another', 'notlocked'];
650*d1f06eb4SAndreas Gohr        $expected = ['wiki:syntax', 'another'];
651*d1f06eb4SAndreas Gohr
652*d1f06eb4SAndreas Gohr        $this->assertEquals(
653*d1f06eb4SAndreas Gohr            $expected,
654*d1f06eb4SAndreas Gohr            $this->remote->call('core.unlockPages', ['pages' => $tounlock])
655*d1f06eb4SAndreas Gohr        );
656*d1f06eb4SAndreas Gohr    }
657*d1f06eb4SAndreas Gohr
658*d1f06eb4SAndreas Gohr    //core.savePage
659*d1f06eb4SAndreas Gohr    public function testSavePage()
660*d1f06eb4SAndreas Gohr    {
661*d1f06eb4SAndreas Gohr        $id = 'putpage';
662*d1f06eb4SAndreas Gohr
663*d1f06eb4SAndreas Gohr        $content = "====Title====\nText";
664*d1f06eb4SAndreas Gohr        $params = [
665*d1f06eb4SAndreas Gohr            'page' => $id,
666*d1f06eb4SAndreas Gohr            'text' => $content,
667*d1f06eb4SAndreas Gohr            'isminor' => false,
668*d1f06eb4SAndreas Gohr            'summary' => 'Summary of nice text'
669*d1f06eb4SAndreas Gohr        ];
670*d1f06eb4SAndreas Gohr        $this->assertTrue($this->remote->call('core.savePage', $params));
671*d1f06eb4SAndreas Gohr        $this->assertEquals($content, rawWiki($id));
672*d1f06eb4SAndreas Gohr
673*d1f06eb4SAndreas Gohr        // remove page
674*d1f06eb4SAndreas Gohr        $params = [
675*d1f06eb4SAndreas Gohr            'page' => $id,
676*d1f06eb4SAndreas Gohr            'text' => '',
677*d1f06eb4SAndreas Gohr        ];
678*d1f06eb4SAndreas Gohr        $this->assertTrue($this->remote->call('core.savePage', $params));
679*d1f06eb4SAndreas Gohr        $this->assertFileNotExists(wikiFN($id));
680*d1f06eb4SAndreas Gohr
681*d1f06eb4SAndreas Gohr        // remove non existing page (reusing above params)
682*d1f06eb4SAndreas Gohr        $e = null;
683*d1f06eb4SAndreas Gohr        try {
684*d1f06eb4SAndreas Gohr            $this->remote->call('core.savePage', $params);
685*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
686*d1f06eb4SAndreas Gohr        }
687*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
688*d1f06eb4SAndreas Gohr        $this->assertEquals(132, $e->getCode());
689*d1f06eb4SAndreas Gohr    }
690*d1f06eb4SAndreas Gohr
691*d1f06eb4SAndreas Gohr    //core.appendPage
692*d1f06eb4SAndreas Gohr    public function testAppendPage()
693*d1f06eb4SAndreas Gohr    {
694*d1f06eb4SAndreas Gohr        $id = 'appendpage';
695*d1f06eb4SAndreas Gohr        $content = 'a test';
696*d1f06eb4SAndreas Gohr        $morecontent = "\nOther text";
697*d1f06eb4SAndreas Gohr        saveWikiText($id, $content, 'local');
698*d1f06eb4SAndreas Gohr
699*d1f06eb4SAndreas Gohr        $params = [
700*d1f06eb4SAndreas Gohr            'page' => $id,
701*d1f06eb4SAndreas Gohr            'text' => $morecontent,
702*d1f06eb4SAndreas Gohr        ];
703*d1f06eb4SAndreas Gohr        $this->assertEquals(true, $this->remote->call('core.appendPage', $params));
704*d1f06eb4SAndreas Gohr        $this->assertEquals($content . $morecontent, rawWiki($id));
705*d1f06eb4SAndreas Gohr    }
706*d1f06eb4SAndreas Gohr
707*d1f06eb4SAndreas Gohr    // endregion
708*d1f06eb4SAndreas Gohr
709*d1f06eb4SAndreas Gohr    // region media
710*d1f06eb4SAndreas Gohr
711*d1f06eb4SAndreas Gohr    // core.listMedia
712*d1f06eb4SAndreas Gohr    public function testListMedia()
713*d1f06eb4SAndreas Gohr    {
714*d1f06eb4SAndreas Gohr        $id = 'wiki:dokuwiki-128.png';
715*d1f06eb4SAndreas Gohr        $file = mediaFN($id);
716*d1f06eb4SAndreas Gohr        $content = file_get_contents($file);
717*d1f06eb4SAndreas Gohr
718*d1f06eb4SAndreas Gohr        $expected = [
719*d1f06eb4SAndreas Gohr            [
720*d1f06eb4SAndreas Gohr                'id' => $id,
721*d1f06eb4SAndreas Gohr                'size' => filesize($file),
722*d1f06eb4SAndreas Gohr                'revision' => filemtime($file),
723*d1f06eb4SAndreas Gohr                'isimage' => true,
724*d1f06eb4SAndreas Gohr                'hash' => md5($content),
725*d1f06eb4SAndreas Gohr                'permission' => 8,
726*d1f06eb4SAndreas Gohr                'author' => '',
727*d1f06eb4SAndreas Gohr            ]
728*d1f06eb4SAndreas Gohr        ];
729*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
730*d1f06eb4SAndreas Gohr            $expected,
731*d1f06eb4SAndreas Gohr            $this->remote->call(
732*d1f06eb4SAndreas Gohr                'core.listMedia',
733*d1f06eb4SAndreas Gohr                [
734*d1f06eb4SAndreas Gohr                    'namespace' => 'wiki',
735*d1f06eb4SAndreas Gohr                    'pattern' => '/128/',
736*d1f06eb4SAndreas Gohr                    'hash' => true,
737*d1f06eb4SAndreas Gohr                ]
738*d1f06eb4SAndreas Gohr            )
739*d1f06eb4SAndreas Gohr        );
740*d1f06eb4SAndreas Gohr    }
741*d1f06eb4SAndreas Gohr
742*d1f06eb4SAndreas Gohr    //core.getRecentMediaChanges
743*d1f06eb4SAndreas Gohr    public function testGetRecentMediaChanges()
74453585189SAndreas Gohr    {
74553585189SAndreas Gohr        global $conf;
74653585189SAndreas Gohr
747*d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser';
74853585189SAndreas Gohr
749*d1f06eb4SAndreas Gohr        $orig = mediaFN('wiki:dokuwiki-128.png');
750*d1f06eb4SAndreas Gohr        $tmp = $conf['tmpdir'] . 'test.png';
75153585189SAndreas Gohr
752*d1f06eb4SAndreas Gohr        $target1 = 'test:image1.png';
753*d1f06eb4SAndreas Gohr        $file1 = mediaFN($target1);
754*d1f06eb4SAndreas Gohr        copy($orig, $tmp);
755*d1f06eb4SAndreas Gohr        media_save(['name' => $tmp], $target1, true, AUTH_UPLOAD, 'rename');
75653585189SAndreas Gohr
757*d1f06eb4SAndreas Gohr        $target2 = 'test:image2.png';
758*d1f06eb4SAndreas Gohr        $file2 = mediaFN($target2);
759*d1f06eb4SAndreas Gohr        copy($orig, $tmp);
760*d1f06eb4SAndreas Gohr        media_save(['name' => $tmp], $target2, true, AUTH_UPLOAD, 'rename');
761*d1f06eb4SAndreas Gohr
76253585189SAndreas Gohr        $expected = [
76353585189SAndreas Gohr            [
764*d1f06eb4SAndreas Gohr                'id' => $target1,
765*d1f06eb4SAndreas Gohr                'revision' => filemtime($file1),
766*d1f06eb4SAndreas Gohr                'author' => 'testuser',
767*d1f06eb4SAndreas Gohr                'ip' => clientIP(),
768*d1f06eb4SAndreas Gohr                'sizechange' => filesize($file1),
769*d1f06eb4SAndreas Gohr                'summary' => 'created',
770*d1f06eb4SAndreas Gohr                'type' => 'C',
771*d1f06eb4SAndreas Gohr            ],
77253585189SAndreas Gohr            [
773*d1f06eb4SAndreas Gohr                'id' => $target2,
774*d1f06eb4SAndreas Gohr                'revision' => filemtime($file2),
775*d1f06eb4SAndreas Gohr                'author' => 'testuser',
776*d1f06eb4SAndreas Gohr                'ip' => clientIP(),
777*d1f06eb4SAndreas Gohr                'sizechange' => filesize($file2),
778*d1f06eb4SAndreas Gohr                'summary' => 'created',
779*d1f06eb4SAndreas Gohr                'type' => 'C',
78053585189SAndreas Gohr            ]
78153585189SAndreas Gohr        ];
782*d1f06eb4SAndreas Gohr
783*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
784*d1f06eb4SAndreas Gohr            $expected,
785*d1f06eb4SAndreas Gohr            $this->remote->call(
786*d1f06eb4SAndreas Gohr                'core.getRecentMediaChanges',
78753585189SAndreas Gohr                [
788*d1f06eb4SAndreas Gohr                    'timestamp' => 0 // all recent changes
78953585189SAndreas Gohr                ]
790*d1f06eb4SAndreas Gohr            )
791*d1f06eb4SAndreas Gohr        );
79253585189SAndreas Gohr    }
79353585189SAndreas Gohr
794*d1f06eb4SAndreas Gohr    //core.getMedia
795*d1f06eb4SAndreas Gohr    public function testGetMedia()
796*d1f06eb4SAndreas Gohr    {
797*d1f06eb4SAndreas Gohr        $id = 'wiki:dokuwiki-128.png';
798*d1f06eb4SAndreas Gohr        $file = mediaFN($id);
799*d1f06eb4SAndreas Gohr        $base64 = base64_encode(file_get_contents($file));
800*d1f06eb4SAndreas Gohr
801*d1f06eb4SAndreas Gohr        $this->assertEquals(
802*d1f06eb4SAndreas Gohr            $base64,
803*d1f06eb4SAndreas Gohr            $this->remote->call('core.getMedia', ['media' => $id])
804*d1f06eb4SAndreas Gohr        );
805*d1f06eb4SAndreas Gohr
806*d1f06eb4SAndreas Gohr        $e = null;
807*d1f06eb4SAndreas Gohr        try {
808*d1f06eb4SAndreas Gohr            $this->remote->call('core.getMedia', ['media' => $id, 'rev' => 1234]);
809*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
810*d1f06eb4SAndreas Gohr        }
811*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
812*d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing revision given');
813*d1f06eb4SAndreas Gohr
814*d1f06eb4SAndreas Gohr        $e = null;
815*d1f06eb4SAndreas Gohr        try {
816*d1f06eb4SAndreas Gohr            $this->remote->call('core.getMedia', ['media' => 'foobar.png']);
817*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
818*d1f06eb4SAndreas Gohr        }
819*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
820*d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing media id given');
821*d1f06eb4SAndreas Gohr    }
822*d1f06eb4SAndreas Gohr
823*d1f06eb4SAndreas Gohr
824*d1f06eb4SAndreas Gohr    //core.getMediaInfo
825*d1f06eb4SAndreas Gohr    public function testGetMediaInfo()
826*d1f06eb4SAndreas Gohr    {
827*d1f06eb4SAndreas Gohr        $id = 'wiki:dokuwiki-128.png';
828*d1f06eb4SAndreas Gohr        $file = mediaFN($id);
829*d1f06eb4SAndreas Gohr
830*d1f06eb4SAndreas Gohr        $expected = [
831*d1f06eb4SAndreas Gohr            'id' => $id,
832*d1f06eb4SAndreas Gohr            'revision' => filemtime($file),
833*d1f06eb4SAndreas Gohr            'author' => '',
834*d1f06eb4SAndreas Gohr            'hash' => md5(file_get_contents($file)),
835*d1f06eb4SAndreas Gohr            'size' => filesize($file),
836*d1f06eb4SAndreas Gohr            'permission' => 8,
837*d1f06eb4SAndreas Gohr            'isimage' => true,
838*d1f06eb4SAndreas Gohr        ];
839*d1f06eb4SAndreas Gohr        $this->assertEqualResult(
840*d1f06eb4SAndreas Gohr            $expected,
841*d1f06eb4SAndreas Gohr            $this->remote->call('core.getMediaInfo', ['media' => $id, 'hash' => true, 'author' => false])
842*d1f06eb4SAndreas Gohr        );
843*d1f06eb4SAndreas Gohr
844*d1f06eb4SAndreas Gohr        $e = null;
845*d1f06eb4SAndreas Gohr        try {
846*d1f06eb4SAndreas Gohr            $this->remote->call('core.getMediaInfo', ['media' => $id, 'rev' => 1234]);
847*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
848*d1f06eb4SAndreas Gohr        }
849*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
850*d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing revision given');
851*d1f06eb4SAndreas Gohr
852*d1f06eb4SAndreas Gohr        $e = null;
853*d1f06eb4SAndreas Gohr        try {
854*d1f06eb4SAndreas Gohr            $this->remote->call('core.getMediaInfo', ['media' => 'foobar.png']);
855*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
856*d1f06eb4SAndreas Gohr        }
857*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
858*d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing media id given');
859*d1f06eb4SAndreas Gohr    }
860*d1f06eb4SAndreas Gohr
861*d1f06eb4SAndreas Gohr    //core.saveMedia
862*d1f06eb4SAndreas Gohr    public function testSaveMedia()
863*d1f06eb4SAndreas Gohr    {
864*d1f06eb4SAndreas Gohr        $orig = mediaFN('wiki:dokuwiki-128.png');
865*d1f06eb4SAndreas Gohr        $base64 = base64_encode(file_get_contents($orig));
866*d1f06eb4SAndreas Gohr
867*d1f06eb4SAndreas Gohr        $target = 'test:putimage.png';
868*d1f06eb4SAndreas Gohr        $targetfile = mediaFN($target);
869*d1f06eb4SAndreas Gohr
870*d1f06eb4SAndreas Gohr        $this->assertTrue($this->remote->call('core.saveMedia', ['media' => $target, 'base64' => $base64]));
871*d1f06eb4SAndreas Gohr        $this->assertFileExists($targetfile);
872*d1f06eb4SAndreas Gohr        $this->assertFileEquals($orig, $targetfile);
873*d1f06eb4SAndreas Gohr    }
874*d1f06eb4SAndreas Gohr
875*d1f06eb4SAndreas Gohr    //core.deleteMedia
876*d1f06eb4SAndreas Gohr    public function testDeleteMedia()
877*d1f06eb4SAndreas Gohr    {
878*d1f06eb4SAndreas Gohr        global $conf;
879*d1f06eb4SAndreas Gohr        global $AUTH_ACL;
880*d1f06eb4SAndreas Gohr        global $USERINFO;
881*d1f06eb4SAndreas Gohr
882*d1f06eb4SAndreas Gohr        $id = 'wiki:dokuwiki-128.png';
883*d1f06eb4SAndreas Gohr        $file = mediaFN($id);
884*d1f06eb4SAndreas Gohr
885*d1f06eb4SAndreas Gohr        // deletion should fail, we only have AUTH_UPLOAD
886*d1f06eb4SAndreas Gohr        $e = null;
887*d1f06eb4SAndreas Gohr        try {
888*d1f06eb4SAndreas Gohr            $this->remote->call('core.deleteMedia', ['media' => $id]);
889*d1f06eb4SAndreas Gohr        } catch (AccessDeniedException $e) {
890*d1f06eb4SAndreas Gohr        }
891*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(AccessDeniedException::class, $e);
892*d1f06eb4SAndreas Gohr        $this->assertEquals(212, $e->getCode(), 'No permission to delete');
893*d1f06eb4SAndreas Gohr        $this->assertFileExists($file);
894*d1f06eb4SAndreas Gohr
895*d1f06eb4SAndreas Gohr        // setup new ACLs
896*d1f06eb4SAndreas Gohr        $conf['useacl'] = 1;
897*d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'john';
898*d1f06eb4SAndreas Gohr        $USERINFO['grps'] = array('user');
899*d1f06eb4SAndreas Gohr        $AUTH_ACL = array(
900*d1f06eb4SAndreas Gohr            '*                  @ALL           0',
901*d1f06eb4SAndreas Gohr            '*                  @user          16',
902*d1f06eb4SAndreas Gohr        );
903*d1f06eb4SAndreas Gohr
904*d1f06eb4SAndreas Gohr        // deletion should work now
905*d1f06eb4SAndreas Gohr        $this->assertTrue($this->remote->call('core.deleteMedia', ['media' => $id]));
906*d1f06eb4SAndreas Gohr        $this->assertFileNotExists($file);
907*d1f06eb4SAndreas Gohr
908*d1f06eb4SAndreas Gohr        clearstatcache(false, $file);
909*d1f06eb4SAndreas Gohr
910*d1f06eb4SAndreas Gohr        // deleting the file again should not work
911*d1f06eb4SAndreas Gohr        $e = null;
912*d1f06eb4SAndreas Gohr        try {
913*d1f06eb4SAndreas Gohr            $this->remote->call('core.deleteMedia', ['media' => $id]);
914*d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
915*d1f06eb4SAndreas Gohr        }
916*d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
917*d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing media id given');
918*d1f06eb4SAndreas Gohr    }
919*d1f06eb4SAndreas Gohr    // endregion
92053585189SAndreas Gohr}
921