xref: /dokuwiki/_test/tests/Remote/ApiCoreTest.php (revision 7383ed4027190de281aa978c38b0a347973abd01)
153585189SAndreas Gohr<?php
253585189SAndreas Gohr
353585189SAndreas Gohrnamespace dokuwiki\test\Remote;
453585189SAndreas Gohr
5d1f06eb4SAndreas Gohruse dokuwiki\Remote\AccessDeniedException;
653585189SAndreas Gohruse dokuwiki\Remote\Api;
753585189SAndreas Gohruse dokuwiki\Remote\ApiCore;
8d1f06eb4SAndreas Gohruse dokuwiki\Remote\RemoteException;
9*7383ed40SAndreas Gohruse dokuwiki\Search\Indexer;
10*7383ed40SAndreas Gohruse dokuwiki\Search\MetadataSearch;
1153585189SAndreas Gohruse dokuwiki\test\mock\AuthPlugin;
1253585189SAndreas Gohr
13d1f06eb4SAndreas 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
57d1f06eb4SAndreas Gohr    /**
58d1f06eb4SAndreas Gohr     * Do an assertion that converts to JSON inbetween
59d1f06eb4SAndreas Gohr     *
60d1f06eb4SAndreas Gohr     * This lets us compare result objects with arrays
61d1f06eb4SAndreas Gohr     */
62d1f06eb4SAndreas Gohr    protected function assertEqualResult($expected, $actual, $msg = '')
6353585189SAndreas Gohr    {
64d1f06eb4SAndreas Gohr        // sort object arrays
65d1f06eb4SAndreas Gohr        if (is_array($actual) && array_key_exists(0, $actual) && is_object($actual[0])) {
66d1f06eb4SAndreas Gohr            sort($actual);
67d1f06eb4SAndreas Gohr            sort($expected);
6853585189SAndreas Gohr        }
6953585189SAndreas Gohr
70d1f06eb4SAndreas Gohr        $expected = json_decode(json_encode($expected), true);
71d1f06eb4SAndreas Gohr        $actual = json_decode(json_encode($actual), true);
72d1f06eb4SAndreas Gohr        $this->assertEquals($expected, $actual, $msg);
7353585189SAndreas Gohr    }
7453585189SAndreas Gohr
75d1f06eb4SAndreas Gohr    // region info
76d1f06eb4SAndreas Gohr
77d1f06eb4SAndreas Gohr    // core.getAPIVersion
78d1f06eb4SAndreas Gohr    public function testGetAPIVersion()
7953585189SAndreas Gohr    {
80d1f06eb4SAndreas Gohr        $this->assertEqualResult(
81d1f06eb4SAndreas Gohr            ApiCore::API_VERSION,
82d1f06eb4SAndreas Gohr            $this->remote->call('core.getAPIVersion')
83d1f06eb4SAndreas Gohr        );
84d1f06eb4SAndreas Gohr    }
85d1f06eb4SAndreas Gohr
86d1f06eb4SAndreas Gohr    // core.getWikiVersion
87d1f06eb4SAndreas Gohr    public function testGetWikiVersion()
88d1f06eb4SAndreas Gohr    {
89d1f06eb4SAndreas Gohr        $this->assertEqualResult(
90d1f06eb4SAndreas Gohr            getVersion(),
91d1f06eb4SAndreas Gohr            $this->remote->call('core.getWikiVersion')
92d1f06eb4SAndreas Gohr        );
93d1f06eb4SAndreas Gohr    }
94d1f06eb4SAndreas Gohr
95d1f06eb4SAndreas Gohr    // core.getWikiTitle
96d1f06eb4SAndreas Gohr    public function testGetWikiTitle()
97d1f06eb4SAndreas Gohr    {
98d1f06eb4SAndreas Gohr        global $conf;
99d1f06eb4SAndreas Gohr        $this->assertEqualResult(
100d1f06eb4SAndreas Gohr            $conf['title'],
101d1f06eb4SAndreas Gohr            $this->remote->call('core.getWikiTitle')
102d1f06eb4SAndreas Gohr        );
103d1f06eb4SAndreas Gohr    }
104d1f06eb4SAndreas Gohr
105d1f06eb4SAndreas Gohr    // core.getWikiTime
106d1f06eb4SAndreas Gohr    public function testGetWikiTime()
107d1f06eb4SAndreas Gohr    {
108d1f06eb4SAndreas Gohr        $this->assertEqualsWithDelta(
109d1f06eb4SAndreas Gohr            time(),
110d1f06eb4SAndreas Gohr            $this->remote->call('core.getWikiTime'),
111d1f06eb4SAndreas Gohr            1 // allow 1 second difference
112d1f06eb4SAndreas Gohr        );
113d1f06eb4SAndreas Gohr    }
114d1f06eb4SAndreas Gohr
115d1f06eb4SAndreas Gohr    // endregion
116d1f06eb4SAndreas Gohr
117d1f06eb4SAndreas Gohr    // region user
118d1f06eb4SAndreas Gohr
119d1f06eb4SAndreas Gohr    // core.login
120d1f06eb4SAndreas Gohr    public function testLogin()
121d1f06eb4SAndreas Gohr    {
122d1f06eb4SAndreas Gohr        $this->markTestIncomplete('Missing test for core.login API Call');
123d1f06eb4SAndreas Gohr    }
124d1f06eb4SAndreas Gohr
125d1f06eb4SAndreas Gohr    // core.logoff
126d1f06eb4SAndreas Gohr    public function testLogoff()
127d1f06eb4SAndreas Gohr    {
128d1f06eb4SAndreas Gohr        $this->markTestIncomplete('Missing test for core.logoff API Call');
129d1f06eb4SAndreas Gohr    }
130d1f06eb4SAndreas Gohr
131d1f06eb4SAndreas Gohr    // core.whoAmI
132d1f06eb4SAndreas Gohr    public function testWhoAmI()
133d1f06eb4SAndreas Gohr    {
134d1f06eb4SAndreas Gohr        $this->markTestIncomplete('Missing test for core.whoAmI API Call');
135d1f06eb4SAndreas Gohr    }
136d1f06eb4SAndreas Gohr
137d1f06eb4SAndreas Gohr    // core.aclCheck -> See also ApiCoreAclCheckTest.php
138d1f06eb4SAndreas Gohr    public function testAclCheck()
139d1f06eb4SAndreas Gohr    {
140d1f06eb4SAndreas Gohr        $id = 'aclpage';
141d1f06eb4SAndreas Gohr
142d1f06eb4SAndreas Gohr        $this->assertEquals(AUTH_UPLOAD, $this->remote->call('core.aclCheck', ['page' => $id]));
143d1f06eb4SAndreas Gohr
144d1f06eb4SAndreas Gohr        global $conf;
145d1f06eb4SAndreas Gohr        global $AUTH_ACL;
146d1f06eb4SAndreas Gohr        global $USERINFO;
147d1f06eb4SAndreas Gohr        $conf['useacl'] = 1;
148d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'john';
149d1f06eb4SAndreas Gohr        $USERINFO['grps'] = ['user'];
150d1f06eb4SAndreas Gohr        $AUTH_ACL = [
151d1f06eb4SAndreas Gohr            '*                  @ALL           0',
152d1f06eb4SAndreas Gohr            '*                  @user          2', //edit
153d1f06eb4SAndreas Gohr        ];
154d1f06eb4SAndreas Gohr
155d1f06eb4SAndreas Gohr        $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', ['page' => $id]));
156d1f06eb4SAndreas Gohr    }
157d1f06eb4SAndreas Gohr
158d1f06eb4SAndreas Gohr
159d1f06eb4SAndreas Gohr    // endregion
160d1f06eb4SAndreas Gohr
161d1f06eb4SAndreas Gohr    // region pages
162d1f06eb4SAndreas Gohr
163d1f06eb4SAndreas Gohr    // core.listPages
164d1f06eb4SAndreas Gohr    public function testlistPagesAll()
165d1f06eb4SAndreas Gohr    {
166d1f06eb4SAndreas Gohr        // all pages depends on index
167*7383ed40SAndreas Gohr        $indexer = new Indexer();
168*7383ed40SAndreas Gohr        $indexer->addPage('wiki:syntax');
169*7383ed40SAndreas Gohr        $indexer->addPage('wiki:dokuwiki');
170d1f06eb4SAndreas Gohr
171d1f06eb4SAndreas Gohr        $file1 = wikiFN('wiki:syntax');
172d1f06eb4SAndreas Gohr        $file2 = wikiFN('wiki:dokuwiki');
173d1f06eb4SAndreas Gohr
17453585189SAndreas Gohr        $expected = [
17553585189SAndreas Gohr            [
176d1f06eb4SAndreas Gohr                'id' => 'wiki:syntax',
177d1f06eb4SAndreas Gohr                'title' => 'wiki:syntax',
178d1f06eb4SAndreas Gohr                'permission' => 8,
17953585189SAndreas Gohr                'size' => filesize($file1),
180d1f06eb4SAndreas Gohr                'revision' => filemtime($file1),
1816535a28fSEduardo Mozart de Oliveira                'hash' => md5(trim(io_readFile($file1))),
182d1f06eb4SAndreas Gohr                'author' => '',
18353585189SAndreas Gohr            ],
18453585189SAndreas Gohr            [
185d1f06eb4SAndreas Gohr                'id' => 'wiki:dokuwiki',
186d1f06eb4SAndreas Gohr                'title' => 'wiki:dokuwiki',
187d1f06eb4SAndreas Gohr                'permission' => 8,
18853585189SAndreas Gohr                'size' => filesize($file2),
189d1f06eb4SAndreas Gohr                'revision' => filemtime($file2),
1906535a28fSEduardo Mozart de Oliveira                'hash' => md5(trim(io_readFile($file2))),
191d1f06eb4SAndreas Gohr                'author' => '',
19253585189SAndreas Gohr            ]
19353585189SAndreas Gohr        ];
194d1f06eb4SAndreas Gohr        $this->assertEqualResult(
195d1f06eb4SAndreas Gohr            $expected,
196d1f06eb4SAndreas Gohr            $this->remote->call(
197d1f06eb4SAndreas Gohr                'core.listPages',
19853585189SAndreas Gohr                [
199d1f06eb4SAndreas Gohr                    'namespace' => '',
20053585189SAndreas Gohr                    'depth' => 0, // 0 for all
201d1f06eb4SAndreas Gohr                    'hash' => true
20253585189SAndreas Gohr                ]
203d1f06eb4SAndreas Gohr            )
204d1f06eb4SAndreas Gohr        );
20553585189SAndreas Gohr    }
20653585189SAndreas Gohr
207d1f06eb4SAndreas Gohr    // core.listPages
208d1f06eb4SAndreas Gohr    public function testListPagesNamespace()
209d1f06eb4SAndreas Gohr    {
210d1f06eb4SAndreas Gohr        $file1 = wikiFN('wiki:syntax');
211d1f06eb4SAndreas Gohr        $file2 = wikiFN('wiki:dokuwiki');
212d1f06eb4SAndreas Gohr        // no indexing needed here
213d1f06eb4SAndreas Gohr
214d1f06eb4SAndreas Gohr        global $conf;
215d1f06eb4SAndreas Gohr        $conf['useheading'] = 1;
216d1f06eb4SAndreas Gohr
217d1f06eb4SAndreas Gohr        $expected = [
218d1f06eb4SAndreas Gohr            [
219d1f06eb4SAndreas Gohr                'id' => 'wiki:syntax',
220d1f06eb4SAndreas Gohr                'title' => 'Formatting Syntax',
221d1f06eb4SAndreas Gohr                'permission' => 8,
222d1f06eb4SAndreas Gohr                'size' => filesize($file1),
223d1f06eb4SAndreas Gohr                'revision' => filemtime($file1),
224d1f06eb4SAndreas Gohr                'hash' => '',
225d1f06eb4SAndreas Gohr                'author' => '',
226d1f06eb4SAndreas Gohr            ],
227d1f06eb4SAndreas Gohr            [
228d1f06eb4SAndreas Gohr                'id' => 'wiki:dokuwiki',
229d1f06eb4SAndreas Gohr                'title' => 'DokuWiki',
230d1f06eb4SAndreas Gohr                'permission' => 8,
231d1f06eb4SAndreas Gohr                'size' => filesize($file2),
232d1f06eb4SAndreas Gohr                'revision' => filemtime($file2),
233d1f06eb4SAndreas Gohr                'hash' => '',
234d1f06eb4SAndreas Gohr                'author' => '',
235d1f06eb4SAndreas Gohr            ],
236d1f06eb4SAndreas Gohr        ];
237d1f06eb4SAndreas Gohr
238d1f06eb4SAndreas Gohr        $this->assertEqualResult(
239d1f06eb4SAndreas Gohr            $expected,
240d1f06eb4SAndreas Gohr            $this->remote->call(
241d1f06eb4SAndreas Gohr                'core.listPages',
242d1f06eb4SAndreas Gohr                [
243d1f06eb4SAndreas Gohr                    'namespace' => 'wiki:',
244d1f06eb4SAndreas Gohr                    'depth' => 1,
245d1f06eb4SAndreas Gohr                ]
246d1f06eb4SAndreas Gohr            )
247d1f06eb4SAndreas Gohr        );
248d1f06eb4SAndreas Gohr    }
249d1f06eb4SAndreas Gohr
250d1f06eb4SAndreas Gohr    // core.searchPages
251d1f06eb4SAndreas Gohr    public function testSearchPages()
25253585189SAndreas Gohr    {
25353585189SAndreas Gohr        $id = 'wiki:syntax';
25453585189SAndreas Gohr        $file = wikiFN($id);
25553585189SAndreas Gohr
256*7383ed40SAndreas Gohr        (new Indexer())->addPage($id); //full text search depends on index
25753585189SAndreas Gohr        $expected = [
25853585189SAndreas Gohr            [
25953585189SAndreas Gohr                'id' => $id,
26053585189SAndreas Gohr                'score' => 1,
261d1f06eb4SAndreas Gohr                'revision' => filemtime($file),
262d1f06eb4SAndreas Gohr                'permission' => 8,
26353585189SAndreas Gohr                'size' => filesize($file),
26453585189SAndreas Gohr                'snippet' => ' a footnote)) by using double parentheses.
26553585189SAndreas Gohr
26653585189SAndreas Gohr===== <strong class="search_hit">Sectioning</strong> =====
26753585189SAndreas Gohr
26853585189SAndreas GohrYou can use up to five different levels of',
269d1f06eb4SAndreas Gohr                'title' => 'wiki:syntax',
270d1f06eb4SAndreas Gohr                'author' => '',
271d1f06eb4SAndreas Gohr                'hash' => '',
27253585189SAndreas Gohr            ]
27353585189SAndreas Gohr        ];
27453585189SAndreas Gohr
275d1f06eb4SAndreas Gohr        $this->assertEqualResult(
276d1f06eb4SAndreas Gohr            $expected,
277d1f06eb4SAndreas Gohr            $this->remote->call(
278d1f06eb4SAndreas Gohr                'core.searchPages',
27953585189SAndreas Gohr                [
280d1f06eb4SAndreas Gohr                    'query' => 'Sectioning'
28153585189SAndreas Gohr                ]
282d1f06eb4SAndreas Gohr            )
283d1f06eb4SAndreas Gohr        );
284d1f06eb4SAndreas Gohr    }
285d1f06eb4SAndreas Gohr
286d1f06eb4SAndreas Gohr    //core.getRecentPageChanges
287d1f06eb4SAndreas Gohr    public function testGetRecentPageChanges()
288d1f06eb4SAndreas Gohr    {
289d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser';
290d1f06eb4SAndreas Gohr
291d1f06eb4SAndreas Gohr        saveWikiText('pageone', 'test', 'test one');
292d1f06eb4SAndreas Gohr        $rev1 = filemtime(wikiFN('pageone'));
293d1f06eb4SAndreas Gohr        saveWikiText('pagetwo', 'test', 'test two');
294d1f06eb4SAndreas Gohr        $rev2 = filemtime(wikiFN('pagetwo'));
29553585189SAndreas Gohr
29653585189SAndreas Gohr        $expected = [
29753585189SAndreas Gohr            [
298d1f06eb4SAndreas Gohr                'id' => 'pageone',
299d1f06eb4SAndreas Gohr                'revision' => $rev1,
300d1f06eb4SAndreas Gohr                'author' => 'testuser',
301d1f06eb4SAndreas Gohr                'sizechange' => 4,
302d1f06eb4SAndreas Gohr                'summary' => 'test one',
303d1f06eb4SAndreas Gohr                'type' => 'C',
304d1f06eb4SAndreas Gohr                'ip' => clientIP(),
305d1f06eb4SAndreas Gohr            ],
306d1f06eb4SAndreas Gohr            [
307d1f06eb4SAndreas Gohr                'id' => 'pagetwo',
308d1f06eb4SAndreas Gohr                'revision' => $rev2,
309d1f06eb4SAndreas Gohr                'author' => 'testuser',
310d1f06eb4SAndreas Gohr                'sizechange' => 4,
311d1f06eb4SAndreas Gohr                'summary' => 'test two',
312d1f06eb4SAndreas Gohr                'type' => 'C',
313d1f06eb4SAndreas Gohr                'ip' => clientIP(),
31453585189SAndreas Gohr            ]
31553585189SAndreas Gohr        ];
31653585189SAndreas Gohr
317d1f06eb4SAndreas Gohr        $this->assertEqualResult(
318d1f06eb4SAndreas Gohr            $expected,
319d1f06eb4SAndreas Gohr            $this->remote->call(
320d1f06eb4SAndreas Gohr                'core.getRecentPageChanges',
32153585189SAndreas Gohr                [
322d1f06eb4SAndreas Gohr                    'timestamp' => 0 // all recent changes
32353585189SAndreas Gohr                ]
324d1f06eb4SAndreas Gohr            )
325d1f06eb4SAndreas Gohr        );
32653585189SAndreas Gohr    }
32753585189SAndreas Gohr
328d1f06eb4SAndreas Gohr    // core.getPage
32953585189SAndreas Gohr    public function testGetPage()
33053585189SAndreas Gohr    {
33153585189SAndreas Gohr        $id = 'pageversion';
33253585189SAndreas Gohr        $file = wikiFN($id);
33353585189SAndreas Gohr
33453585189SAndreas Gohr        saveWikiText($id, 'first version', 'first');
33553585189SAndreas Gohr        $rev1 = filemtime($file);
33653585189SAndreas Gohr        clearstatcache(false, $file);
33753585189SAndreas Gohr        $this->waitForTick(true);
33853585189SAndreas Gohr        saveWikiText($id, 'second version', 'second');
33953585189SAndreas Gohr        $rev2 = filemtime($file);
34053585189SAndreas Gohr
341d1f06eb4SAndreas Gohr        $this->assertEqualResult(
342d1f06eb4SAndreas Gohr            'second version',
343d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => $id, 'rev' => 0]),
344d1f06eb4SAndreas Gohr            'no revision given -> current'
345d1f06eb4SAndreas Gohr        );
34653585189SAndreas Gohr
347d1f06eb4SAndreas Gohr        $this->assertEqualResult(
348d1f06eb4SAndreas Gohr            'first version',
349d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => $id, 'rev' => $rev1]),
350d1f06eb4SAndreas Gohr            '1st revision given'
351d1f06eb4SAndreas Gohr        );
35253585189SAndreas Gohr
353d1f06eb4SAndreas Gohr        $this->assertEqualResult(
354d1f06eb4SAndreas Gohr            'second version',
355d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => $id, 'rev' => $rev2]),
356d1f06eb4SAndreas Gohr            '2nd revision given'
357d1f06eb4SAndreas Gohr        );
35853585189SAndreas Gohr
359d1f06eb4SAndreas Gohr        $this->assertEqualResult(
360d1f06eb4SAndreas Gohr            '',
361d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => $id, 'rev' => 1234]),
362d1f06eb4SAndreas Gohr            'Non existing revision given'
363d1f06eb4SAndreas Gohr        );
36453585189SAndreas Gohr
365d1f06eb4SAndreas Gohr        $this->assertEqualResult(
366d1f06eb4SAndreas Gohr            '',
367d1f06eb4SAndreas Gohr            $this->remote->call('core.getPage', ['page' => 'foobar', 'rev' => 1234]),
368d1f06eb4SAndreas Gohr            'Non existing page given'
369d1f06eb4SAndreas Gohr        );
37053585189SAndreas Gohr    }
37153585189SAndreas Gohr
372d1f06eb4SAndreas Gohr    //core.getPageHTML
37353585189SAndreas Gohr    public function testGetPageHTMLVersion()
37453585189SAndreas Gohr    {
37553585189SAndreas Gohr        $id = 'htmltest';
37653585189SAndreas Gohr        $file = wikiFN($id);
37753585189SAndreas Gohr
37853585189SAndreas Gohr        $content1 = "====Title====\nText";
37953585189SAndreas Gohr        $html1 = "\n<h3 class=\"sectionedit1\" id=\"title\">Title</h3>\n<div class=\"level3\">\n\n<p>\nText\n</p>\n\n</div>\n";
38053585189SAndreas Gohr        $content2 = "====Foobar====\nText Bamm";
38153585189SAndreas 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";
38253585189SAndreas Gohr
38353585189SAndreas Gohr        saveWikiText($id, $content1, 'first');
38453585189SAndreas Gohr        $rev1 = filemtime($file);
38553585189SAndreas Gohr        clearstatcache(false, $file);
38653585189SAndreas Gohr        $this->waitForTick(true);
38753585189SAndreas Gohr        saveWikiText($id, $content2, 'second');
38853585189SAndreas Gohr        $rev2 = filemtime($file);
38953585189SAndreas Gohr
390d1f06eb4SAndreas Gohr        $this->assertEqualResult(
391d1f06eb4SAndreas Gohr            $html2,
392d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => 0]),
393d1f06eb4SAndreas Gohr            'no revision given -> current'
394d1f06eb4SAndreas Gohr        );
39553585189SAndreas Gohr
396d1f06eb4SAndreas Gohr        $this->assertEqualResult(
397d1f06eb4SAndreas Gohr            $html1,
398d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => $rev1]),
399d1f06eb4SAndreas Gohr            '1st revision given'
400d1f06eb4SAndreas Gohr        );
40153585189SAndreas Gohr
402d1f06eb4SAndreas Gohr        $this->assertEqualResult(
403d1f06eb4SAndreas Gohr            $html2,
404d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => $rev2]),
405d1f06eb4SAndreas Gohr            '2nd revision given'
406d1f06eb4SAndreas Gohr        );
40753585189SAndreas Gohr
408d1f06eb4SAndreas Gohr        $e = null;
409d1f06eb4SAndreas Gohr        try {
410d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => 1234]);
411d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
412d1f06eb4SAndreas Gohr        }
413d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
414d1f06eb4SAndreas Gohr        $this->assertEquals(121, $e->getCode(), 'Non existing revision given');
41553585189SAndreas Gohr
416d1f06eb4SAndreas Gohr        $e = null;
417d1f06eb4SAndreas Gohr        try {
418d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageHTML', ['page' => 'foobar', 'rev' => 1234]);
419d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
420d1f06eb4SAndreas Gohr        }
421d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
422d1f06eb4SAndreas Gohr        $this->assertEquals(121, $e->getCode(), 'Non existing page given');
42353585189SAndreas Gohr    }
42453585189SAndreas Gohr
425d1f06eb4SAndreas Gohr    //core.getPageInfo
42653585189SAndreas Gohr    public function testGetPageInfo()
42753585189SAndreas Gohr    {
42853585189SAndreas Gohr        $id = 'pageinfo';
42953585189SAndreas Gohr        $file = wikiFN($id);
43053585189SAndreas Gohr
431d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser';
43253585189SAndreas Gohr
43353585189SAndreas Gohr        saveWikiText($id, 'first version', 'first');
43453585189SAndreas Gohr        $rev1 = filemtime($file);
43553585189SAndreas Gohr        clearstatcache(false, $file);
43653585189SAndreas Gohr        $this->waitForTick(true);
43753585189SAndreas Gohr        saveWikiText($id, 'second version', 'second');
43853585189SAndreas Gohr        $rev2 = filemtime($file);
43953585189SAndreas Gohr
44053585189SAndreas Gohr        $expected = [
441d1f06eb4SAndreas Gohr            'id' => $id,
442d1f06eb4SAndreas Gohr            'revision' => $rev2,
443d1f06eb4SAndreas Gohr            'author' => 'testuser',
4446535a28fSEduardo Mozart de Oliveira            'hash' => md5(trim(io_readFile($file))),
445d1f06eb4SAndreas Gohr            'title' => $id,
446d1f06eb4SAndreas Gohr            'size' => filesize($file),
447d1f06eb4SAndreas Gohr            'permission' => 8,
44853585189SAndreas Gohr        ];
449d1f06eb4SAndreas Gohr        $this->assertEqualResult(
450d1f06eb4SAndreas Gohr            $expected,
451d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => 0, 'hash' => true, 'author' => true]),
452d1f06eb4SAndreas Gohr            'no revision given -> current'
453d1f06eb4SAndreas Gohr        );
45453585189SAndreas Gohr
45553585189SAndreas Gohr        $expected = [
456d1f06eb4SAndreas Gohr            'id' => $id,
457d1f06eb4SAndreas Gohr            'revision' => $rev1,
458d1f06eb4SAndreas Gohr            'author' => '',
459d1f06eb4SAndreas Gohr            'hash' => '',
460d1f06eb4SAndreas Gohr            'title' => $id,
461d1f06eb4SAndreas Gohr            'size' => filesize(wikiFN($id, $rev1)),
462d1f06eb4SAndreas Gohr            'permission' => 8,
46353585189SAndreas Gohr        ];
464d1f06eb4SAndreas Gohr        $this->assertEqualResult(
465d1f06eb4SAndreas Gohr            $expected,
466d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => $rev1]),
467d1f06eb4SAndreas Gohr            '1st revision given'
468d1f06eb4SAndreas Gohr        );
46953585189SAndreas Gohr
47053585189SAndreas Gohr        $expected = [
471d1f06eb4SAndreas Gohr            'id' => $id,
472d1f06eb4SAndreas Gohr            'revision' => $rev2,
473d1f06eb4SAndreas Gohr            'author' => '',
474d1f06eb4SAndreas Gohr            'hash' => '',
475d1f06eb4SAndreas Gohr            'title' => $id,
476d1f06eb4SAndreas Gohr            'size' => filesize(wikiFN($id, $rev2)),
477d1f06eb4SAndreas Gohr            'permission' => 8,
47853585189SAndreas Gohr        ];
479d1f06eb4SAndreas Gohr        $this->assertEqualResult(
480d1f06eb4SAndreas Gohr            $expected,
481d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => $rev2]),
482d1f06eb4SAndreas Gohr            '2nd revision given'
483d1f06eb4SAndreas Gohr        );
484d1f06eb4SAndreas Gohr
485d1f06eb4SAndreas Gohr        $e = null;
486d1f06eb4SAndreas Gohr        try {
487d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => 1234]);
488d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
489d1f06eb4SAndreas Gohr        }
490d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
491d1f06eb4SAndreas Gohr        $this->assertEquals(121, $e->getCode(), 'Non existing revision given');
492d1f06eb4SAndreas Gohr
493d1f06eb4SAndreas Gohr        $e = null;
494d1f06eb4SAndreas Gohr        try {
495d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageInfo', ['page' => 'foobar', 'rev' => 1234]);
496d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
497d1f06eb4SAndreas Gohr        }
498d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
499d1f06eb4SAndreas Gohr        $this->assertEquals(121, $e->getCode(), 'Non existing page given');
50053585189SAndreas Gohr    }
50153585189SAndreas Gohr
502d1f06eb4SAndreas Gohr    //core.getPageHistory
503d1f06eb4SAndreas Gohr    public function testGetPageHistory()
50453585189SAndreas Gohr    {
50553585189SAndreas Gohr        global $conf;
50653585189SAndreas Gohr
50753585189SAndreas Gohr        $id = 'revpage';
50853585189SAndreas Gohr        $file = wikiFN($id);
50953585189SAndreas Gohr
51053585189SAndreas Gohr        $rev = [];
51153585189SAndreas Gohr        for ($i = 0; $i < 6; $i++) {
51253585189SAndreas Gohr            $this->waitForTick();
51353585189SAndreas Gohr            saveWikiText($id, "rev$i", "rev$i");
51453585189SAndreas Gohr            clearstatcache(false, $file);
51553585189SAndreas Gohr            $rev[$i] = filemtime($file);
51653585189SAndreas Gohr        }
51753585189SAndreas Gohr
518d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => 0];
519d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
520d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
52153585189SAndreas Gohr        $this->assertEquals(6, count($versions));
522d1f06eb4SAndreas Gohr        $this->assertEquals($rev[5], $versions[0]['revision']);
523d1f06eb4SAndreas Gohr        $this->assertEquals($rev[4], $versions[1]['revision']);
524d1f06eb4SAndreas Gohr        $this->assertEquals($rev[3], $versions[2]['revision']);
525d1f06eb4SAndreas Gohr        $this->assertEquals($rev[2], $versions[3]['revision']);
526d1f06eb4SAndreas Gohr        $this->assertEquals($rev[1], $versions[4]['revision']);
527d1f06eb4SAndreas Gohr        $this->assertEquals($rev[0], $versions[5]['revision']);
52853585189SAndreas Gohr
529d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => 1]; // offset 1
530d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
531d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
53253585189SAndreas Gohr        $this->assertEquals(5, count($versions));
533d1f06eb4SAndreas Gohr        $this->assertEquals($rev[4], $versions[0]['revision']);
534d1f06eb4SAndreas Gohr        $this->assertEquals($rev[3], $versions[1]['revision']);
535d1f06eb4SAndreas Gohr        $this->assertEquals($rev[2], $versions[2]['revision']);
536d1f06eb4SAndreas Gohr        $this->assertEquals($rev[1], $versions[3]['revision']);
537d1f06eb4SAndreas Gohr        $this->assertEquals($rev[0], $versions[4]['revision']);
53853585189SAndreas Gohr
53953585189SAndreas Gohr        $conf['recent'] = 3; //set number of results per page
54053585189SAndreas Gohr
541d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => 0]; // first page
542d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
543d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
54453585189SAndreas Gohr        $this->assertEquals(3, count($versions));
545d1f06eb4SAndreas Gohr        $this->assertEquals($rev[5], $versions[0]['revision']);
546d1f06eb4SAndreas Gohr        $this->assertEquals($rev[4], $versions[1]['revision']);
547d1f06eb4SAndreas Gohr        $this->assertEquals($rev[3], $versions[2]['revision']);
54853585189SAndreas Gohr
549d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => $conf['recent']]; // second page
550d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
551d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
55253585189SAndreas Gohr        $this->assertEquals(3, count($versions));
553d1f06eb4SAndreas Gohr        $this->assertEquals($rev[2], $versions[0]['revision']);
554d1f06eb4SAndreas Gohr        $this->assertEquals($rev[1], $versions[1]['revision']);
555d1f06eb4SAndreas Gohr        $this->assertEquals($rev[0], $versions[2]['revision']);
55653585189SAndreas Gohr
557d1f06eb4SAndreas Gohr        $params = ['page' => $id, 'first' => $conf['recent'] * 2]; // third page
558d1f06eb4SAndreas Gohr        $versions = $this->remote->call('core.getPageHistory', $params);
559d1f06eb4SAndreas Gohr        $versions = json_decode(json_encode($versions), true);
56053585189SAndreas Gohr        $this->assertEquals(0, count($versions));
56153585189SAndreas Gohr    }
56253585189SAndreas Gohr
563d1f06eb4SAndreas Gohr    //core.getPageLinks
564d1f06eb4SAndreas Gohr    public function testGetPageLinks()
56553585189SAndreas Gohr    {
56653585189SAndreas Gohr        $localdoku = [
56753585189SAndreas Gohr            'type' => 'local',
56853585189SAndreas Gohr            'page' => 'DokuWiki',
56953585189SAndreas Gohr            'href' => DOKU_BASE . DOKU_SCRIPT . '?id=DokuWiki'
57053585189SAndreas Gohr        ];
571d1f06eb4SAndreas Gohr        $expected = [
57253585189SAndreas Gohr            $localdoku,
57353585189SAndreas Gohr            [
57453585189SAndreas Gohr                'type' => 'extern',
57553585189SAndreas Gohr                'page' => 'http://www.freelists.org',
57653585189SAndreas Gohr                'href' => 'http://www.freelists.org'
57753585189SAndreas Gohr            ],
57853585189SAndreas Gohr            [
579d1f06eb4SAndreas Gohr                'type' => 'interwiki',
580d1f06eb4SAndreas Gohr                'page' => 'rfc>1855',
58153585189SAndreas Gohr                'href' => 'https://tools.ietf.org/html/rfc1855'
58253585189SAndreas Gohr            ],
58353585189SAndreas Gohr            [
58453585189SAndreas Gohr                'type' => 'extern',
58553585189SAndreas Gohr                'page' => 'http://www.catb.org/~esr/faqs/smart-questions.html',
58653585189SAndreas Gohr                'href' => 'http://www.catb.org/~esr/faqs/smart-questions.html'
58753585189SAndreas Gohr            ],
58853585189SAndreas Gohr            $localdoku,
58953585189SAndreas Gohr            $localdoku
59053585189SAndreas Gohr        ];
591d1f06eb4SAndreas Gohr
592d1f06eb4SAndreas Gohr        $this->assertEqualResult(
593d1f06eb4SAndreas Gohr            $expected,
594d1f06eb4SAndreas Gohr            $this->remote->call('core.getPageLinks', ['page' => 'mailinglist'])
595d1f06eb4SAndreas Gohr        );
596d1f06eb4SAndreas Gohr
597d1f06eb4SAndreas Gohr        $this->expectExceptionCode(121);
598d1f06eb4SAndreas Gohr        $this->remote->call('core.getPageLinks', ['page' => 'foobar']);
59953585189SAndreas Gohr    }
60053585189SAndreas Gohr
601d1f06eb4SAndreas Gohr    //core.getPageBackLinks
602d1f06eb4SAndreas Gohr    public function testGetPageBackLinks()
603d1f06eb4SAndreas Gohr    {
604d1f06eb4SAndreas Gohr        saveWikiText('linky', '[[wiki:syntax]]', 'test');
605d1f06eb4SAndreas Gohr        // backlinks need index
606*7383ed40SAndreas Gohr        $indexer = new Indexer();
607*7383ed40SAndreas Gohr        $indexer->addPage('wiki:syntax');
608*7383ed40SAndreas Gohr        $indexer->addPage('linky');
609d1f06eb4SAndreas Gohr
610d1f06eb4SAndreas Gohr        $result = $this->remote->call('core.getPageBackLinks', ['page' => 'wiki:syntax']);
611d1f06eb4SAndreas Gohr        $this->assertTrue(count($result) > 0);
612*7383ed40SAndreas Gohr        $this->assertEqualResult((new MetadataSearch())->backlinks('wiki:syntax'), $result);
613d1f06eb4SAndreas Gohr
614d1f06eb4SAndreas Gohr        $this->assertEquals([], $this->remote->call('core.getPageBackLinks', ['page' => 'foobar']));
615d1f06eb4SAndreas Gohr    }
616d1f06eb4SAndreas Gohr
617d1f06eb4SAndreas Gohr    //core.lockPages
618d1f06eb4SAndreas Gohr    public function testLockPages()
619d1f06eb4SAndreas Gohr    {
620d1f06eb4SAndreas Gohr        // lock a first set of pages
621d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser1';
622d1f06eb4SAndreas Gohr        $tolock = ['wiki:dokuwiki', 'nonexisting'];
623d1f06eb4SAndreas Gohr        $this->assertEquals(
624d1f06eb4SAndreas Gohr            $tolock,
625d1f06eb4SAndreas Gohr            $this->remote->call('core.lockPages', ['pages' => $tolock]),
626d1f06eb4SAndreas Gohr            'all pages should lock'
627d1f06eb4SAndreas Gohr        );
628d1f06eb4SAndreas Gohr
629d1f06eb4SAndreas Gohr        // now we're someone else
630d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser2';
631d1f06eb4SAndreas Gohr        $tolock = ['wiki:dokuwiki', 'nonexisting', 'wiki:syntax', 'another'];
632d1f06eb4SAndreas Gohr        $expected = ['wiki:syntax', 'another'];
633d1f06eb4SAndreas Gohr        $this->assertEquals(
634d1f06eb4SAndreas Gohr            $expected,
635d1f06eb4SAndreas Gohr            $this->remote->call('core.lockPages', ['pages' => $tolock]),
636d1f06eb4SAndreas Gohr            'only half the pages should lock'
637d1f06eb4SAndreas Gohr        );
638d1f06eb4SAndreas Gohr    }
639d1f06eb4SAndreas Gohr
640d1f06eb4SAndreas Gohr    // core.unlockPages
641d1f06eb4SAndreas Gohr    public function testUnlockPages()
642d1f06eb4SAndreas Gohr    {
643d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser1';
644d1f06eb4SAndreas Gohr        lock('wiki:dokuwiki');
645d1f06eb4SAndreas Gohr        lock('nonexisting');
646d1f06eb4SAndreas Gohr
647d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser2';
648d1f06eb4SAndreas Gohr        lock('wiki:syntax');
649d1f06eb4SAndreas Gohr        lock('another');
650d1f06eb4SAndreas Gohr
651d1f06eb4SAndreas Gohr        $tounlock = ['wiki:dokuwiki', 'nonexisting', 'wiki:syntax', 'another', 'notlocked'];
652d1f06eb4SAndreas Gohr        $expected = ['wiki:syntax', 'another'];
653d1f06eb4SAndreas Gohr
654d1f06eb4SAndreas Gohr        $this->assertEquals(
655d1f06eb4SAndreas Gohr            $expected,
656d1f06eb4SAndreas Gohr            $this->remote->call('core.unlockPages', ['pages' => $tounlock])
657d1f06eb4SAndreas Gohr        );
658d1f06eb4SAndreas Gohr    }
659d1f06eb4SAndreas Gohr
660d1f06eb4SAndreas Gohr    //core.savePage
661d1f06eb4SAndreas Gohr    public function testSavePage()
662d1f06eb4SAndreas Gohr    {
663d1f06eb4SAndreas Gohr        $id = 'putpage';
664d1f06eb4SAndreas Gohr
665d1f06eb4SAndreas Gohr        $content = "====Title====\nText";
666d1f06eb4SAndreas Gohr        $params = [
667d1f06eb4SAndreas Gohr            'page' => $id,
668d1f06eb4SAndreas Gohr            'text' => $content,
669d1f06eb4SAndreas Gohr            'isminor' => false,
670d1f06eb4SAndreas Gohr            'summary' => 'Summary of nice text'
671d1f06eb4SAndreas Gohr        ];
672d1f06eb4SAndreas Gohr        $this->assertTrue($this->remote->call('core.savePage', $params));
673d1f06eb4SAndreas Gohr        $this->assertEquals($content, rawWiki($id));
674d1f06eb4SAndreas Gohr
675d1f06eb4SAndreas Gohr        // remove page
676d1f06eb4SAndreas Gohr        $params = [
677d1f06eb4SAndreas Gohr            'page' => $id,
678d1f06eb4SAndreas Gohr            'text' => '',
679d1f06eb4SAndreas Gohr        ];
680d1f06eb4SAndreas Gohr        $this->assertTrue($this->remote->call('core.savePage', $params));
6819ad2b913SAndreas Gohr        $this->assertFileDoesNotExist(wikiFN($id));
682d1f06eb4SAndreas Gohr
683d1f06eb4SAndreas Gohr        // remove non existing page (reusing above params)
684d1f06eb4SAndreas Gohr        $e = null;
685d1f06eb4SAndreas Gohr        try {
686d1f06eb4SAndreas Gohr            $this->remote->call('core.savePage', $params);
687d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
688d1f06eb4SAndreas Gohr        }
689d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
690d1f06eb4SAndreas Gohr        $this->assertEquals(132, $e->getCode());
691d1f06eb4SAndreas Gohr    }
692d1f06eb4SAndreas Gohr
693d1f06eb4SAndreas Gohr    //core.appendPage
694d1f06eb4SAndreas Gohr    public function testAppendPage()
695d1f06eb4SAndreas Gohr    {
696d1f06eb4SAndreas Gohr        $id = 'appendpage';
697d1f06eb4SAndreas Gohr        $content = 'a test';
698d1f06eb4SAndreas Gohr        $morecontent = "\nOther text";
699d1f06eb4SAndreas Gohr        saveWikiText($id, $content, 'local');
700d1f06eb4SAndreas Gohr
701d1f06eb4SAndreas Gohr        $params = [
702d1f06eb4SAndreas Gohr            'page' => $id,
703d1f06eb4SAndreas Gohr            'text' => $morecontent,
704d1f06eb4SAndreas Gohr        ];
705d1f06eb4SAndreas Gohr        $this->assertEquals(true, $this->remote->call('core.appendPage', $params));
706d1f06eb4SAndreas Gohr        $this->assertEquals($content . $morecontent, rawWiki($id));
707d1f06eb4SAndreas Gohr    }
708d1f06eb4SAndreas Gohr
709d1f06eb4SAndreas Gohr    // endregion
710d1f06eb4SAndreas Gohr
711d1f06eb4SAndreas Gohr    // region media
712d1f06eb4SAndreas Gohr
713d1f06eb4SAndreas Gohr    // core.listMedia
714d1f06eb4SAndreas Gohr    public function testListMedia()
715d1f06eb4SAndreas Gohr    {
716d1f06eb4SAndreas Gohr        $id = 'wiki:dokuwiki-128.png';
717d1f06eb4SAndreas Gohr        $file = mediaFN($id);
718d1f06eb4SAndreas Gohr        $content = file_get_contents($file);
719d1f06eb4SAndreas Gohr
720d1f06eb4SAndreas Gohr        $expected = [
721d1f06eb4SAndreas Gohr            [
722d1f06eb4SAndreas Gohr                'id' => $id,
723d1f06eb4SAndreas Gohr                'size' => filesize($file),
724d1f06eb4SAndreas Gohr                'revision' => filemtime($file),
725d1f06eb4SAndreas Gohr                'isimage' => true,
726d1f06eb4SAndreas Gohr                'hash' => md5($content),
727d1f06eb4SAndreas Gohr                'permission' => 8,
728d1f06eb4SAndreas Gohr                'author' => '',
729d1f06eb4SAndreas Gohr            ]
730d1f06eb4SAndreas Gohr        ];
731d1f06eb4SAndreas Gohr        $this->assertEqualResult(
732d1f06eb4SAndreas Gohr            $expected,
733d1f06eb4SAndreas Gohr            $this->remote->call(
734d1f06eb4SAndreas Gohr                'core.listMedia',
735d1f06eb4SAndreas Gohr                [
736d1f06eb4SAndreas Gohr                    'namespace' => 'wiki',
737d1f06eb4SAndreas Gohr                    'pattern' => '/128/',
738d1f06eb4SAndreas Gohr                    'hash' => true,
739d1f06eb4SAndreas Gohr                ]
740d1f06eb4SAndreas Gohr            )
741d1f06eb4SAndreas Gohr        );
742d1f06eb4SAndreas Gohr    }
743d1f06eb4SAndreas Gohr
744d1f06eb4SAndreas Gohr    //core.getRecentMediaChanges
745d1f06eb4SAndreas Gohr    public function testGetRecentMediaChanges()
74653585189SAndreas Gohr    {
74753585189SAndreas Gohr        global $conf;
74853585189SAndreas Gohr
749d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'testuser';
75053585189SAndreas Gohr
751d1f06eb4SAndreas Gohr        $orig = mediaFN('wiki:dokuwiki-128.png');
752d1f06eb4SAndreas Gohr        $tmp = $conf['tmpdir'] . 'test.png';
75353585189SAndreas Gohr
754d1f06eb4SAndreas Gohr        $target1 = 'test:image1.png';
755d1f06eb4SAndreas Gohr        $file1 = mediaFN($target1);
756d1f06eb4SAndreas Gohr        copy($orig, $tmp);
757d1f06eb4SAndreas Gohr        media_save(['name' => $tmp], $target1, true, AUTH_UPLOAD, 'rename');
75853585189SAndreas Gohr
759d1f06eb4SAndreas Gohr        $target2 = 'test:image2.png';
760d1f06eb4SAndreas Gohr        $file2 = mediaFN($target2);
761d1f06eb4SAndreas Gohr        copy($orig, $tmp);
762d1f06eb4SAndreas Gohr        media_save(['name' => $tmp], $target2, true, AUTH_UPLOAD, 'rename');
763d1f06eb4SAndreas Gohr
76453585189SAndreas Gohr        $expected = [
76553585189SAndreas Gohr            [
766d1f06eb4SAndreas Gohr                'id' => $target1,
767d1f06eb4SAndreas Gohr                'revision' => filemtime($file1),
768d1f06eb4SAndreas Gohr                'author' => 'testuser',
769d1f06eb4SAndreas Gohr                'ip' => clientIP(),
770d1f06eb4SAndreas Gohr                'sizechange' => filesize($file1),
771d1f06eb4SAndreas Gohr                'summary' => 'created',
772d1f06eb4SAndreas Gohr                'type' => 'C',
773d1f06eb4SAndreas Gohr            ],
77453585189SAndreas Gohr            [
775d1f06eb4SAndreas Gohr                'id' => $target2,
776d1f06eb4SAndreas Gohr                'revision' => filemtime($file2),
777d1f06eb4SAndreas Gohr                'author' => 'testuser',
778d1f06eb4SAndreas Gohr                'ip' => clientIP(),
779d1f06eb4SAndreas Gohr                'sizechange' => filesize($file2),
780d1f06eb4SAndreas Gohr                'summary' => 'created',
781d1f06eb4SAndreas Gohr                'type' => 'C',
78253585189SAndreas Gohr            ]
78353585189SAndreas Gohr        ];
784d1f06eb4SAndreas Gohr
785d1f06eb4SAndreas Gohr        $this->assertEqualResult(
786d1f06eb4SAndreas Gohr            $expected,
787d1f06eb4SAndreas Gohr            $this->remote->call(
788d1f06eb4SAndreas Gohr                'core.getRecentMediaChanges',
78953585189SAndreas Gohr                [
790d1f06eb4SAndreas Gohr                    'timestamp' => 0 // all recent changes
79153585189SAndreas Gohr                ]
792d1f06eb4SAndreas Gohr            )
793d1f06eb4SAndreas Gohr        );
79453585189SAndreas Gohr    }
79553585189SAndreas Gohr
796d1f06eb4SAndreas Gohr    //core.getMedia
797d1f06eb4SAndreas Gohr    public function testGetMedia()
798d1f06eb4SAndreas Gohr    {
799d1f06eb4SAndreas Gohr        $id = 'wiki:dokuwiki-128.png';
800d1f06eb4SAndreas Gohr        $file = mediaFN($id);
801d1f06eb4SAndreas Gohr        $base64 = base64_encode(file_get_contents($file));
802d1f06eb4SAndreas Gohr
803d1f06eb4SAndreas Gohr        $this->assertEquals(
804d1f06eb4SAndreas Gohr            $base64,
805d1f06eb4SAndreas Gohr            $this->remote->call('core.getMedia', ['media' => $id])
806d1f06eb4SAndreas Gohr        );
807d1f06eb4SAndreas Gohr
808d1f06eb4SAndreas Gohr        $e = null;
809d1f06eb4SAndreas Gohr        try {
810d1f06eb4SAndreas Gohr            $this->remote->call('core.getMedia', ['media' => $id, 'rev' => 1234]);
811d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
812d1f06eb4SAndreas Gohr        }
813d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
814d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing revision given');
815d1f06eb4SAndreas Gohr
816d1f06eb4SAndreas Gohr        $e = null;
817d1f06eb4SAndreas Gohr        try {
818d1f06eb4SAndreas Gohr            $this->remote->call('core.getMedia', ['media' => 'foobar.png']);
819d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
820d1f06eb4SAndreas Gohr        }
821d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
822d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing media id given');
823d1f06eb4SAndreas Gohr    }
824d1f06eb4SAndreas Gohr
825d1f06eb4SAndreas Gohr
826d1f06eb4SAndreas Gohr    //core.getMediaInfo
827d1f06eb4SAndreas Gohr    public function testGetMediaInfo()
828d1f06eb4SAndreas Gohr    {
829d1f06eb4SAndreas Gohr        $id = 'wiki:dokuwiki-128.png';
830d1f06eb4SAndreas Gohr        $file = mediaFN($id);
831d1f06eb4SAndreas Gohr
832d1f06eb4SAndreas Gohr        $expected = [
833d1f06eb4SAndreas Gohr            'id' => $id,
834d1f06eb4SAndreas Gohr            'revision' => filemtime($file),
835d1f06eb4SAndreas Gohr            'author' => '',
836d1f06eb4SAndreas Gohr            'hash' => md5(file_get_contents($file)),
837d1f06eb4SAndreas Gohr            'size' => filesize($file),
838d1f06eb4SAndreas Gohr            'permission' => 8,
839d1f06eb4SAndreas Gohr            'isimage' => true,
840d1f06eb4SAndreas Gohr        ];
841d1f06eb4SAndreas Gohr        $this->assertEqualResult(
842d1f06eb4SAndreas Gohr            $expected,
843d1f06eb4SAndreas Gohr            $this->remote->call('core.getMediaInfo', ['media' => $id, 'hash' => true, 'author' => false])
844d1f06eb4SAndreas Gohr        );
845d1f06eb4SAndreas Gohr
846d1f06eb4SAndreas Gohr        $e = null;
847d1f06eb4SAndreas Gohr        try {
848d1f06eb4SAndreas Gohr            $this->remote->call('core.getMediaInfo', ['media' => $id, 'rev' => 1234]);
849d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
850d1f06eb4SAndreas Gohr        }
851d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
852d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing revision given');
853d1f06eb4SAndreas Gohr
854d1f06eb4SAndreas Gohr        $e = null;
855d1f06eb4SAndreas Gohr        try {
856d1f06eb4SAndreas Gohr            $this->remote->call('core.getMediaInfo', ['media' => 'foobar.png']);
857d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
858d1f06eb4SAndreas Gohr        }
859d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
860d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing media id given');
861d1f06eb4SAndreas Gohr    }
862d1f06eb4SAndreas Gohr
86361d21e86Skuangfio    //core.getMediaHistory
86461d21e86Skuangfio    public function testGetMediaHistory()
86561d21e86Skuangfio    {
86661d21e86Skuangfio        global $conf;
86761d21e86Skuangfio
86861d21e86Skuangfio        $_SERVER['REMOTE_USER'] = 'testuser';
86961d21e86Skuangfio
87061d21e86Skuangfio        //image to be uploaded
87161d21e86Skuangfio        $orig = mediaFN('wiki:dokuwiki-128.png');
87261d21e86Skuangfio        $tmp = $conf['tmpdir'] . 'test.png';
87361d21e86Skuangfio
87461d21e86Skuangfio        //create image to be revised
87561d21e86Skuangfio        $id = 'test:image3.png';
87661d21e86Skuangfio        $media = mediaFN($id);
87761d21e86Skuangfio
87861d21e86Skuangfio        $rev = [];
87961d21e86Skuangfio        for ($i = 0; $i < 2; $i++) {
88061d21e86Skuangfio            $this->waitForTick();
88161d21e86Skuangfio            copy($orig, $tmp);
88261d21e86Skuangfio            media_save(['name' => $tmp], $id, true, AUTH_UPLOAD, 'rename');
88361d21e86Skuangfio            $rev[$i] = filemtime($media);
88461d21e86Skuangfio        }
88561d21e86Skuangfio
88661d21e86Skuangfio        $params = ['media' => $id, 'first' => 0]; // offset 0
88761d21e86Skuangfio        $versions = $this->remote->call('core.getMediaHistory', $params);
88861d21e86Skuangfio        $versions = json_decode(json_encode($versions), true);
88961d21e86Skuangfio        $this->assertEquals(2, count($versions));
89061d21e86Skuangfio        $this->assertEquals($rev[1], $versions[0]['revision']);
89161d21e86Skuangfio        $this->assertEquals($rev[0], $versions[1]['revision']);
89261d21e86Skuangfio
89361d21e86Skuangfio        $params = ['media' => $id, 'first' => 1]; // offset 1
89461d21e86Skuangfio        $versions = $this->remote->call('core.getMediaHistory', $params);
89561d21e86Skuangfio        $versions = json_decode(json_encode($versions), true);
89661d21e86Skuangfio        $this->assertEquals(1, count($versions));
89761d21e86Skuangfio        $this->assertEquals($rev[0], $versions[0]['revision']);
89861d21e86Skuangfio
89961d21e86Skuangfio        $params = ['media' => $id, 'first' => 2]; // offset 2
90061d21e86Skuangfio        $versions = $this->remote->call('core.getMediaHistory', $params);
90161d21e86Skuangfio        $versions = json_decode(json_encode($versions), true);
90261d21e86Skuangfio        $this->assertEquals(0, count($versions));
90361d21e86Skuangfio
90461d21e86Skuangfio        $params = ['media' => $id, 'first' => 2]; // offset 3
90561d21e86Skuangfio        $versions = $this->remote->call('core.getMediaHistory', $params);
90661d21e86Skuangfio        $versions = json_decode(json_encode($versions), true);
90761d21e86Skuangfio        $this->assertEquals(0, count($versions));
90861d21e86Skuangfio    }
90961d21e86Skuangfio
910d1f06eb4SAndreas Gohr    //core.saveMedia
911d1f06eb4SAndreas Gohr    public function testSaveMedia()
912d1f06eb4SAndreas Gohr    {
913d1f06eb4SAndreas Gohr        $orig = mediaFN('wiki:dokuwiki-128.png');
914d1f06eb4SAndreas Gohr        $base64 = base64_encode(file_get_contents($orig));
915d1f06eb4SAndreas Gohr
916d1f06eb4SAndreas Gohr        $target = 'test:putimage.png';
917d1f06eb4SAndreas Gohr        $targetfile = mediaFN($target);
918d1f06eb4SAndreas Gohr
919d1f06eb4SAndreas Gohr        $this->assertTrue($this->remote->call('core.saveMedia', ['media' => $target, 'base64' => $base64]));
920d1f06eb4SAndreas Gohr        $this->assertFileExists($targetfile);
921d1f06eb4SAndreas Gohr        $this->assertFileEquals($orig, $targetfile);
922d1f06eb4SAndreas Gohr    }
923d1f06eb4SAndreas Gohr
924d1f06eb4SAndreas Gohr    //core.deleteMedia
925d1f06eb4SAndreas Gohr    public function testDeleteMedia()
926d1f06eb4SAndreas Gohr    {
927d1f06eb4SAndreas Gohr        global $conf;
928d1f06eb4SAndreas Gohr        global $AUTH_ACL;
929d1f06eb4SAndreas Gohr        global $USERINFO;
930d1f06eb4SAndreas Gohr
931d1f06eb4SAndreas Gohr        $id = 'wiki:dokuwiki-128.png';
932d1f06eb4SAndreas Gohr        $file = mediaFN($id);
933d1f06eb4SAndreas Gohr
934d1f06eb4SAndreas Gohr        // deletion should fail, we only have AUTH_UPLOAD
935d1f06eb4SAndreas Gohr        $e = null;
936d1f06eb4SAndreas Gohr        try {
937d1f06eb4SAndreas Gohr            $this->remote->call('core.deleteMedia', ['media' => $id]);
938d1f06eb4SAndreas Gohr        } catch (AccessDeniedException $e) {
939d1f06eb4SAndreas Gohr        }
940d1f06eb4SAndreas Gohr        $this->assertInstanceOf(AccessDeniedException::class, $e);
941d1f06eb4SAndreas Gohr        $this->assertEquals(212, $e->getCode(), 'No permission to delete');
942d1f06eb4SAndreas Gohr        $this->assertFileExists($file);
943d1f06eb4SAndreas Gohr
944d1f06eb4SAndreas Gohr        // setup new ACLs
945d1f06eb4SAndreas Gohr        $conf['useacl'] = 1;
946d1f06eb4SAndreas Gohr        $_SERVER['REMOTE_USER'] = 'john';
947d1f06eb4SAndreas Gohr        $USERINFO['grps'] = array('user');
948d1f06eb4SAndreas Gohr        $AUTH_ACL = array(
949d1f06eb4SAndreas Gohr            '*                  @ALL           0',
950d1f06eb4SAndreas Gohr            '*                  @user          16',
951d1f06eb4SAndreas Gohr        );
952d1f06eb4SAndreas Gohr
953d1f06eb4SAndreas Gohr        // deletion should work now
954d1f06eb4SAndreas Gohr        $this->assertTrue($this->remote->call('core.deleteMedia', ['media' => $id]));
9559ad2b913SAndreas Gohr        $this->assertFileDoesNotExist($file);
956d1f06eb4SAndreas Gohr
957d1f06eb4SAndreas Gohr        clearstatcache(false, $file);
958d1f06eb4SAndreas Gohr
959d1f06eb4SAndreas Gohr        // deleting the file again should not work
960d1f06eb4SAndreas Gohr        $e = null;
961d1f06eb4SAndreas Gohr        try {
962d1f06eb4SAndreas Gohr            $this->remote->call('core.deleteMedia', ['media' => $id]);
963d1f06eb4SAndreas Gohr        } catch (RemoteException $e) {
964d1f06eb4SAndreas Gohr        }
965d1f06eb4SAndreas Gohr        $this->assertInstanceOf(RemoteException::class, $e);
966d1f06eb4SAndreas Gohr        $this->assertEquals(221, $e->getCode(), 'Non existing media id given');
967d1f06eb4SAndreas Gohr    }
968d1f06eb4SAndreas Gohr    // endregion
96953585189SAndreas Gohr}
970