1<?php 2 3namespace dokuwiki\test\Remote; 4 5use dokuwiki\Extension\Event; 6use dokuwiki\Remote\AccessDeniedException; 7use dokuwiki\Remote\Api; 8use dokuwiki\Remote\ApiCore; 9use dokuwiki\Remote\RemoteException; 10use dokuwiki\test\mock\AuthDeletePlugin; 11use dokuwiki\test\mock\AuthPlugin; 12 13 14/** 15 * Class remoteapicore_test 16 */ 17class ApiCoreTest extends \DokuWikiTest 18{ 19 20 protected $userinfo; 21 protected $oldAuthAcl; 22 /** @var Api */ 23 protected $remote; 24 25 public function setUp(): void 26 { 27 // we need a clean setup before each single test: 28 \DokuWikiTest::setUpBeforeClass(); 29 30 parent::setUp(); 31 global $conf; 32 global $USERINFO; 33 global $AUTH_ACL; 34 global $auth; 35 $this->oldAuthAcl = $AUTH_ACL; 36 $this->userinfo = $USERINFO; 37 $auth = new AuthPlugin(); 38 39 $conf['remote'] = 1; 40 $conf['remoteuser'] = '@user'; 41 $conf['useacl'] = 0; 42 43 $this->remote = new Api(); 44 } 45 46 public function tearDown(): void 47 { 48 parent::tearDown(); 49 50 global $USERINFO; 51 global $AUTH_ACL; 52 53 $USERINFO = $this->userinfo; 54 $AUTH_ACL = $this->oldAuthAcl; 55 } 56 57 /** 58 * Do an assertion that converts to JSON inbetween 59 * 60 * This lets us compare result objects with arrays 61 */ 62 protected function assertEqualResult($expected, $actual, $msg = '') 63 { 64 // sort object arrays 65 if (is_array($actual) && array_key_exists(0, $actual) && is_object($actual[0])) { 66 sort($actual); 67 sort($expected); 68 } 69 70 $expected = json_decode(json_encode($expected), true); 71 $actual = json_decode(json_encode($actual), true); 72 $this->assertEquals($expected, $actual, $msg); 73 } 74 75 // region info 76 77 // core.getAPIVersion 78 public function testGetAPIVersion() 79 { 80 $this->assertEqualResult( 81 ApiCore::API_VERSION, 82 $this->remote->call('core.getAPIVersion') 83 ); 84 } 85 86 // core.getWikiVersion 87 public function testGetWikiVersion() 88 { 89 $this->assertEqualResult( 90 getVersion(), 91 $this->remote->call('core.getWikiVersion') 92 ); 93 } 94 95 // core.getWikiTitle 96 public function testGetWikiTitle() 97 { 98 global $conf; 99 $this->assertEqualResult( 100 $conf['title'], 101 $this->remote->call('core.getWikiTitle') 102 ); 103 } 104 105 // core.getWikiTime 106 public function testGetWikiTime() 107 { 108 $this->assertEqualsWithDelta( 109 time(), 110 $this->remote->call('core.getWikiTime'), 111 1 // allow 1 second difference 112 ); 113 } 114 115 // endregion 116 117 // region user 118 119 // core.login 120 public function testLogin() 121 { 122 $this->markTestIncomplete('Missing test for core.login API Call'); 123 } 124 125 // core.logoff 126 public function testLogoff() 127 { 128 $this->markTestIncomplete('Missing test for core.logoff API Call'); 129 } 130 131 // core.whoAmI 132 public function testWhoAmI() 133 { 134 $this->markTestIncomplete('Missing test for core.whoAmI API Call'); 135 } 136 137 // core.aclCheck -> See also ApiCoreAclCheckTest.php 138 public function testAclCheck() 139 { 140 $id = 'aclpage'; 141 142 $this->assertEquals(AUTH_UPLOAD, $this->remote->call('core.aclCheck', ['page' => $id])); 143 144 global $conf; 145 global $AUTH_ACL; 146 global $USERINFO; 147 $conf['useacl'] = 1; 148 $_SERVER['REMOTE_USER'] = 'john'; 149 $USERINFO['grps'] = ['user']; 150 $AUTH_ACL = [ 151 '* @ALL 0', 152 '* @user 2', //edit 153 ]; 154 155 $this->assertEquals(AUTH_EDIT, $this->remote->call('core.aclCheck', ['page' => $id])); 156 } 157 158 159 // endregion 160 161 // region pages 162 163 // core.listPages 164 public function testlistPagesAll() 165 { 166 // all pages depends on index 167 idx_addPage('wiki:syntax'); 168 idx_addPage('wiki:dokuwiki'); 169 170 $file1 = wikiFN('wiki:syntax'); 171 $file2 = wikiFN('wiki:dokuwiki'); 172 173 $expected = [ 174 [ 175 'id' => 'wiki:syntax', 176 'title' => 'wiki:syntax', 177 'permission' => 8, 178 'size' => filesize($file1), 179 'revision' => filemtime($file1), 180 'hash' => md5(io_readFile($file1)), 181 'author' => '', 182 ], 183 [ 184 'id' => 'wiki:dokuwiki', 185 'title' => 'wiki:dokuwiki', 186 'permission' => 8, 187 'size' => filesize($file2), 188 'revision' => filemtime($file2), 189 'hash' => md5(io_readFile($file2)), 190 'author' => '', 191 ] 192 ]; 193 $this->assertEqualResult( 194 $expected, 195 $this->remote->call( 196 'core.listPages', 197 [ 198 'namespace' => '', 199 'depth' => 0, // 0 for all 200 'hash' => true 201 ] 202 ) 203 ); 204 } 205 206 // core.listPages 207 public function testListPagesNamespace() 208 { 209 $file1 = wikiFN('wiki:syntax'); 210 $file2 = wikiFN('wiki:dokuwiki'); 211 // no indexing needed here 212 213 global $conf; 214 $conf['useheading'] = 1; 215 216 $expected = [ 217 [ 218 'id' => 'wiki:syntax', 219 'title' => 'Formatting Syntax', 220 'permission' => 8, 221 'size' => filesize($file1), 222 'revision' => filemtime($file1), 223 'hash' => '', 224 'author' => '', 225 ], 226 [ 227 'id' => 'wiki:dokuwiki', 228 'title' => 'DokuWiki', 229 'permission' => 8, 230 'size' => filesize($file2), 231 'revision' => filemtime($file2), 232 'hash' => '', 233 'author' => '', 234 ], 235 ]; 236 237 $this->assertEqualResult( 238 $expected, 239 $this->remote->call( 240 'core.listPages', 241 [ 242 'namespace' => 'wiki:', 243 'depth' => 1, 244 ] 245 ) 246 ); 247 } 248 249 // core.searchPages 250 public function testSearchPages() 251 { 252 $id = 'wiki:syntax'; 253 $file = wikiFN($id); 254 255 idx_addPage($id); //full text search depends on index 256 $expected = [ 257 [ 258 'id' => $id, 259 'score' => 1, 260 'revision' => filemtime($file), 261 'permission' => 8, 262 'size' => filesize($file), 263 'snippet' => ' a footnote)) by using double parentheses. 264 265===== <strong class="search_hit">Sectioning</strong> ===== 266 267You can use up to five different levels of', 268 'title' => 'wiki:syntax', 269 'author' => '', 270 'hash' => '', 271 ] 272 ]; 273 274 $this->assertEqualResult( 275 $expected, 276 $this->remote->call( 277 'core.searchPages', 278 [ 279 'query' => 'Sectioning' 280 ] 281 ) 282 ); 283 } 284 285 //core.getRecentPageChanges 286 public function testGetRecentPageChanges() 287 { 288 $_SERVER['REMOTE_USER'] = 'testuser'; 289 290 saveWikiText('pageone', 'test', 'test one'); 291 $rev1 = filemtime(wikiFN('pageone')); 292 saveWikiText('pagetwo', 'test', 'test two'); 293 $rev2 = filemtime(wikiFN('pagetwo')); 294 295 $expected = [ 296 [ 297 'id' => 'pageone', 298 'revision' => $rev1, 299 'author' => 'testuser', 300 'sizechange' => 4, 301 'summary' => 'test one', 302 'type' => 'C', 303 'ip' => clientIP(), 304 ], 305 [ 306 'id' => 'pagetwo', 307 'revision' => $rev2, 308 'author' => 'testuser', 309 'sizechange' => 4, 310 'summary' => 'test two', 311 'type' => 'C', 312 'ip' => clientIP(), 313 ] 314 ]; 315 316 $this->assertEqualResult( 317 $expected, 318 $this->remote->call( 319 'core.getRecentPageChanges', 320 [ 321 'timestamp' => 0 // all recent changes 322 ] 323 ) 324 ); 325 } 326 327 // core.getPage 328 public function testGetPage() 329 { 330 $id = 'pageversion'; 331 $file = wikiFN($id); 332 333 saveWikiText($id, 'first version', 'first'); 334 $rev1 = filemtime($file); 335 clearstatcache(false, $file); 336 $this->waitForTick(true); 337 saveWikiText($id, 'second version', 'second'); 338 $rev2 = filemtime($file); 339 340 $this->assertEqualResult( 341 'second version', 342 $this->remote->call('core.getPage', ['page' => $id, 'rev' => 0]), 343 'no revision given -> current' 344 ); 345 346 $this->assertEqualResult( 347 'first version', 348 $this->remote->call('core.getPage', ['page' => $id, 'rev' => $rev1]), 349 '1st revision given' 350 ); 351 352 $this->assertEqualResult( 353 'second version', 354 $this->remote->call('core.getPage', ['page' => $id, 'rev' => $rev2]), 355 '2nd revision given' 356 ); 357 358 $this->assertEqualResult( 359 '', 360 $this->remote->call('core.getPage', ['page' => $id, 'rev' => 1234]), 361 'Non existing revision given' 362 ); 363 364 $this->assertEqualResult( 365 '', 366 $this->remote->call('core.getPage', ['page' => 'foobar', 'rev' => 1234]), 367 'Non existing page given' 368 ); 369 } 370 371 //core.getPageHTML 372 public function testGetPageHTMLVersion() 373 { 374 $id = 'htmltest'; 375 $file = wikiFN($id); 376 377 $content1 = "====Title====\nText"; 378 $html1 = "\n<h3 class=\"sectionedit1\" id=\"title\">Title</h3>\n<div class=\"level3\">\n\n<p>\nText\n</p>\n\n</div>\n"; 379 $content2 = "====Foobar====\nText Bamm"; 380 $html2 = "\n<h3 class=\"sectionedit1\" id=\"foobar\">Foobar</h3>\n<div class=\"level3\">\n\n<p>\nText Bamm\n</p>\n\n</div>\n"; 381 382 saveWikiText($id, $content1, 'first'); 383 $rev1 = filemtime($file); 384 clearstatcache(false, $file); 385 $this->waitForTick(true); 386 saveWikiText($id, $content2, 'second'); 387 $rev2 = filemtime($file); 388 389 $this->assertEqualResult( 390 $html2, 391 $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => 0]), 392 'no revision given -> current' 393 ); 394 395 $this->assertEqualResult( 396 $html1, 397 $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => $rev1]), 398 '1st revision given' 399 ); 400 401 $this->assertEqualResult( 402 $html2, 403 $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => $rev2]), 404 '2nd revision given' 405 ); 406 407 $e = null; 408 try { 409 $this->remote->call('core.getPageHTML', ['page' => $id, 'rev' => 1234]); 410 } catch (RemoteException $e) { 411 } 412 $this->assertInstanceOf(RemoteException::class, $e); 413 $this->assertEquals(121, $e->getCode(), 'Non existing revision given'); 414 415 $e = null; 416 try { 417 $this->remote->call('core.getPageHTML', ['page' => 'foobar', 'rev' => 1234]); 418 } catch (RemoteException $e) { 419 } 420 $this->assertInstanceOf(RemoteException::class, $e); 421 $this->assertEquals(121, $e->getCode(), 'Non existing page given'); 422 } 423 424 //core.getPageInfo 425 public function testGetPageInfo() 426 { 427 $id = 'pageinfo'; 428 $file = wikiFN($id); 429 430 $_SERVER['REMOTE_USER'] = 'testuser'; 431 432 saveWikiText($id, 'first version', 'first'); 433 $rev1 = filemtime($file); 434 clearstatcache(false, $file); 435 $this->waitForTick(true); 436 saveWikiText($id, 'second version', 'second'); 437 $rev2 = filemtime($file); 438 439 $expected = [ 440 'id' => $id, 441 'revision' => $rev2, 442 'author' => 'testuser', 443 'hash' => md5(io_readFile($file)), 444 'title' => $id, 445 'size' => filesize($file), 446 'permission' => 8, 447 ]; 448 $this->assertEqualResult( 449 $expected, 450 $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => 0, 'hash' => true, 'author' => true]), 451 'no revision given -> current' 452 ); 453 454 $expected = [ 455 'id' => $id, 456 'revision' => $rev1, 457 'author' => '', 458 'hash' => '', 459 'title' => $id, 460 'size' => filesize(wikiFN($id, $rev1)), 461 'permission' => 8, 462 ]; 463 $this->assertEqualResult( 464 $expected, 465 $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => $rev1]), 466 '1st revision given' 467 ); 468 469 $expected = [ 470 'id' => $id, 471 'revision' => $rev2, 472 'author' => '', 473 'hash' => '', 474 'title' => $id, 475 'size' => filesize(wikiFN($id, $rev2)), 476 'permission' => 8, 477 ]; 478 $this->assertEqualResult( 479 $expected, 480 $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => $rev2]), 481 '2nd revision given' 482 ); 483 484 $e = null; 485 try { 486 $this->remote->call('core.getPageInfo', ['page' => $id, 'rev' => 1234]); 487 } catch (RemoteException $e) { 488 } 489 $this->assertInstanceOf(RemoteException::class, $e); 490 $this->assertEquals(121, $e->getCode(), 'Non existing revision given'); 491 492 $e = null; 493 try { 494 $this->remote->call('core.getPageInfo', ['page' => 'foobar', 'rev' => 1234]); 495 } catch (RemoteException $e) { 496 } 497 $this->assertInstanceOf(RemoteException::class, $e); 498 $this->assertEquals(121, $e->getCode(), 'Non existing page given'); 499 } 500 501 //core.getPageHistory 502 public function testGetPageHistory() 503 { 504 global $conf; 505 506 $id = 'revpage'; 507 $file = wikiFN($id); 508 509 $rev = []; 510 for ($i = 0; $i < 6; $i++) { 511 $this->waitForTick(); 512 saveWikiText($id, "rev$i", "rev$i"); 513 clearstatcache(false, $file); 514 $rev[$i] = filemtime($file); 515 } 516 517 $params = ['page' => $id, 'first' => 0]; 518 $versions = $this->remote->call('core.getPageHistory', $params); 519 $versions = json_decode(json_encode($versions), true); 520 $this->assertEquals(6, count($versions)); 521 $this->assertEquals($rev[5], $versions[0]['revision']); 522 $this->assertEquals($rev[4], $versions[1]['revision']); 523 $this->assertEquals($rev[3], $versions[2]['revision']); 524 $this->assertEquals($rev[2], $versions[3]['revision']); 525 $this->assertEquals($rev[1], $versions[4]['revision']); 526 $this->assertEquals($rev[0], $versions[5]['revision']); 527 528 $params = ['page' => $id, 'first' => 1]; // offset 1 529 $versions = $this->remote->call('core.getPageHistory', $params); 530 $versions = json_decode(json_encode($versions), true); 531 $this->assertEquals(5, count($versions)); 532 $this->assertEquals($rev[4], $versions[0]['revision']); 533 $this->assertEquals($rev[3], $versions[1]['revision']); 534 $this->assertEquals($rev[2], $versions[2]['revision']); 535 $this->assertEquals($rev[1], $versions[3]['revision']); 536 $this->assertEquals($rev[0], $versions[4]['revision']); 537 538 $conf['recent'] = 3; //set number of results per page 539 540 $params = ['page' => $id, 'first' => 0]; // first page 541 $versions = $this->remote->call('core.getPageHistory', $params); 542 $versions = json_decode(json_encode($versions), true); 543 $this->assertEquals(3, count($versions)); 544 $this->assertEquals($rev[5], $versions[0]['revision']); 545 $this->assertEquals($rev[4], $versions[1]['revision']); 546 $this->assertEquals($rev[3], $versions[2]['revision']); 547 548 $params = ['page' => $id, 'first' => $conf['recent']]; // second page 549 $versions = $this->remote->call('core.getPageHistory', $params); 550 $versions = json_decode(json_encode($versions), true); 551 $this->assertEquals(3, count($versions)); 552 $this->assertEquals($rev[2], $versions[0]['revision']); 553 $this->assertEquals($rev[1], $versions[1]['revision']); 554 $this->assertEquals($rev[0], $versions[2]['revision']); 555 556 $params = ['page' => $id, 'first' => $conf['recent'] * 2]; // third page 557 $versions = $this->remote->call('core.getPageHistory', $params); 558 $versions = json_decode(json_encode($versions), true); 559 $this->assertEquals(0, count($versions)); 560 } 561 562 //core.getPageLinks 563 public function testGetPageLinks() 564 { 565 $localdoku = [ 566 'type' => 'local', 567 'page' => 'DokuWiki', 568 'href' => DOKU_BASE . DOKU_SCRIPT . '?id=DokuWiki' 569 ]; 570 $expected = [ 571 $localdoku, 572 [ 573 'type' => 'extern', 574 'page' => 'http://www.freelists.org', 575 'href' => 'http://www.freelists.org' 576 ], 577 [ 578 'type' => 'interwiki', 579 'page' => 'rfc>1855', 580 'href' => 'https://tools.ietf.org/html/rfc1855' 581 ], 582 [ 583 'type' => 'extern', 584 'page' => 'http://www.catb.org/~esr/faqs/smart-questions.html', 585 'href' => 'http://www.catb.org/~esr/faqs/smart-questions.html' 586 ], 587 $localdoku, 588 $localdoku 589 ]; 590 591 $this->assertEqualResult( 592 $expected, 593 $this->remote->call('core.getPageLinks', ['page' => 'mailinglist']) 594 ); 595 596 $this->expectExceptionCode(121); 597 $this->remote->call('core.getPageLinks', ['page' => 'foobar']); 598 } 599 600 //core.getPageBackLinks 601 public function testGetPageBackLinks() 602 { 603 saveWikiText('linky', '[[wiki:syntax]]', 'test'); 604 // backlinks need index 605 idx_addPage('wiki:syntax'); 606 idx_addPage('linky'); 607 608 $result = $this->remote->call('core.getPageBackLinks', ['page' => 'wiki:syntax']); 609 $this->assertTrue(count($result) > 0); 610 $this->assertEqualResult(ft_backlinks('wiki:syntax'), $result); 611 612 $this->assertEquals([], $this->remote->call('core.getPageBackLinks', ['page' => 'foobar'])); 613 } 614 615 //core.lockPages 616 public function testLockPages() 617 { 618 // lock a first set of pages 619 $_SERVER['REMOTE_USER'] = 'testuser1'; 620 $tolock = ['wiki:dokuwiki', 'nonexisting']; 621 $this->assertEquals( 622 $tolock, 623 $this->remote->call('core.lockPages', ['pages' => $tolock]), 624 'all pages should lock' 625 ); 626 627 // now we're someone else 628 $_SERVER['REMOTE_USER'] = 'testuser2'; 629 $tolock = ['wiki:dokuwiki', 'nonexisting', 'wiki:syntax', 'another']; 630 $expected = ['wiki:syntax', 'another']; 631 $this->assertEquals( 632 $expected, 633 $this->remote->call('core.lockPages', ['pages' => $tolock]), 634 'only half the pages should lock' 635 ); 636 } 637 638 // core.unlockPages 639 public function testUnlockPages() 640 { 641 $_SERVER['REMOTE_USER'] = 'testuser1'; 642 lock('wiki:dokuwiki'); 643 lock('nonexisting'); 644 645 $_SERVER['REMOTE_USER'] = 'testuser2'; 646 lock('wiki:syntax'); 647 lock('another'); 648 649 $tounlock = ['wiki:dokuwiki', 'nonexisting', 'wiki:syntax', 'another', 'notlocked']; 650 $expected = ['wiki:syntax', 'another']; 651 652 $this->assertEquals( 653 $expected, 654 $this->remote->call('core.unlockPages', ['pages' => $tounlock]) 655 ); 656 } 657 658 //core.savePage 659 public function testSavePage() 660 { 661 $id = 'putpage'; 662 663 $content = "====Title====\nText"; 664 $params = [ 665 'page' => $id, 666 'text' => $content, 667 'isminor' => false, 668 'summary' => 'Summary of nice text' 669 ]; 670 $this->assertTrue($this->remote->call('core.savePage', $params)); 671 $this->assertEquals($content, rawWiki($id)); 672 673 // remove page 674 $params = [ 675 'page' => $id, 676 'text' => '', 677 ]; 678 $this->assertTrue($this->remote->call('core.savePage', $params)); 679 $this->assertFileNotExists(wikiFN($id)); 680 681 // remove non existing page (reusing above params) 682 $e = null; 683 try { 684 $this->remote->call('core.savePage', $params); 685 } catch (RemoteException $e) { 686 } 687 $this->assertInstanceOf(RemoteException::class, $e); 688 $this->assertEquals(132, $e->getCode()); 689 } 690 691 //core.appendPage 692 public function testAppendPage() 693 { 694 $id = 'appendpage'; 695 $content = 'a test'; 696 $morecontent = "\nOther text"; 697 saveWikiText($id, $content, 'local'); 698 699 $params = [ 700 'page' => $id, 701 'text' => $morecontent, 702 ]; 703 $this->assertEquals(true, $this->remote->call('core.appendPage', $params)); 704 $this->assertEquals($content . $morecontent, rawWiki($id)); 705 } 706 707 // endregion 708 709 // region media 710 711 // core.listMedia 712 public function testListMedia() 713 { 714 $id = 'wiki:dokuwiki-128.png'; 715 $file = mediaFN($id); 716 $content = file_get_contents($file); 717 718 $expected = [ 719 [ 720 'id' => $id, 721 'size' => filesize($file), 722 'revision' => filemtime($file), 723 'isimage' => true, 724 'hash' => md5($content), 725 'permission' => 8, 726 'author' => '', 727 ] 728 ]; 729 $this->assertEqualResult( 730 $expected, 731 $this->remote->call( 732 'core.listMedia', 733 [ 734 'namespace' => 'wiki', 735 'pattern' => '/128/', 736 'hash' => true, 737 ] 738 ) 739 ); 740 } 741 742 //core.getRecentMediaChanges 743 public function testGetRecentMediaChanges() 744 { 745 global $conf; 746 747 $_SERVER['REMOTE_USER'] = 'testuser'; 748 749 $orig = mediaFN('wiki:dokuwiki-128.png'); 750 $tmp = $conf['tmpdir'] . 'test.png'; 751 752 $target1 = 'test:image1.png'; 753 $file1 = mediaFN($target1); 754 copy($orig, $tmp); 755 media_save(['name' => $tmp], $target1, true, AUTH_UPLOAD, 'rename'); 756 757 $target2 = 'test:image2.png'; 758 $file2 = mediaFN($target2); 759 copy($orig, $tmp); 760 media_save(['name' => $tmp], $target2, true, AUTH_UPLOAD, 'rename'); 761 762 $expected = [ 763 [ 764 'id' => $target1, 765 'revision' => filemtime($file1), 766 'author' => 'testuser', 767 'ip' => clientIP(), 768 'sizechange' => filesize($file1), 769 'summary' => 'created', 770 'type' => 'C', 771 ], 772 [ 773 'id' => $target2, 774 'revision' => filemtime($file2), 775 'author' => 'testuser', 776 'ip' => clientIP(), 777 'sizechange' => filesize($file2), 778 'summary' => 'created', 779 'type' => 'C', 780 ] 781 ]; 782 783 $this->assertEqualResult( 784 $expected, 785 $this->remote->call( 786 'core.getRecentMediaChanges', 787 [ 788 'timestamp' => 0 // all recent changes 789 ] 790 ) 791 ); 792 } 793 794 //core.getMedia 795 public function testGetMedia() 796 { 797 $id = 'wiki:dokuwiki-128.png'; 798 $file = mediaFN($id); 799 $base64 = base64_encode(file_get_contents($file)); 800 801 $this->assertEquals( 802 $base64, 803 $this->remote->call('core.getMedia', ['media' => $id]) 804 ); 805 806 $e = null; 807 try { 808 $this->remote->call('core.getMedia', ['media' => $id, 'rev' => 1234]); 809 } catch (RemoteException $e) { 810 } 811 $this->assertInstanceOf(RemoteException::class, $e); 812 $this->assertEquals(221, $e->getCode(), 'Non existing revision given'); 813 814 $e = null; 815 try { 816 $this->remote->call('core.getMedia', ['media' => 'foobar.png']); 817 } catch (RemoteException $e) { 818 } 819 $this->assertInstanceOf(RemoteException::class, $e); 820 $this->assertEquals(221, $e->getCode(), 'Non existing media id given'); 821 } 822 823 824 //core.getMediaInfo 825 public function testGetMediaInfo() 826 { 827 $id = 'wiki:dokuwiki-128.png'; 828 $file = mediaFN($id); 829 830 $expected = [ 831 'id' => $id, 832 'revision' => filemtime($file), 833 'author' => '', 834 'hash' => md5(file_get_contents($file)), 835 'size' => filesize($file), 836 'permission' => 8, 837 'isimage' => true, 838 ]; 839 $this->assertEqualResult( 840 $expected, 841 $this->remote->call('core.getMediaInfo', ['media' => $id, 'hash' => true, 'author' => false]) 842 ); 843 844 $e = null; 845 try { 846 $this->remote->call('core.getMediaInfo', ['media' => $id, 'rev' => 1234]); 847 } catch (RemoteException $e) { 848 } 849 $this->assertInstanceOf(RemoteException::class, $e); 850 $this->assertEquals(221, $e->getCode(), 'Non existing revision given'); 851 852 $e = null; 853 try { 854 $this->remote->call('core.getMediaInfo', ['media' => 'foobar.png']); 855 } catch (RemoteException $e) { 856 } 857 $this->assertInstanceOf(RemoteException::class, $e); 858 $this->assertEquals(221, $e->getCode(), 'Non existing media id given'); 859 } 860 861 //core.saveMedia 862 public function testSaveMedia() 863 { 864 $orig = mediaFN('wiki:dokuwiki-128.png'); 865 $base64 = base64_encode(file_get_contents($orig)); 866 867 $target = 'test:putimage.png'; 868 $targetfile = mediaFN($target); 869 870 $this->assertTrue($this->remote->call('core.saveMedia', ['media' => $target, 'base64' => $base64])); 871 $this->assertFileExists($targetfile); 872 $this->assertFileEquals($orig, $targetfile); 873 } 874 875 //core.deleteMedia 876 public function testDeleteMedia() 877 { 878 global $conf; 879 global $AUTH_ACL; 880 global $USERINFO; 881 882 $id = 'wiki:dokuwiki-128.png'; 883 $file = mediaFN($id); 884 885 // deletion should fail, we only have AUTH_UPLOAD 886 $e = null; 887 try { 888 $this->remote->call('core.deleteMedia', ['media' => $id]); 889 } catch (AccessDeniedException $e) { 890 } 891 $this->assertInstanceOf(AccessDeniedException::class, $e); 892 $this->assertEquals(212, $e->getCode(), 'No permission to delete'); 893 $this->assertFileExists($file); 894 895 // setup new ACLs 896 $conf['useacl'] = 1; 897 $_SERVER['REMOTE_USER'] = 'john'; 898 $USERINFO['grps'] = array('user'); 899 $AUTH_ACL = array( 900 '* @ALL 0', 901 '* @user 16', 902 ); 903 904 // deletion should work now 905 $this->assertTrue($this->remote->call('core.deleteMedia', ['media' => $id])); 906 $this->assertFileNotExists($file); 907 908 clearstatcache(false, $file); 909 910 // deleting the file again should not work 911 $e = null; 912 try { 913 $this->remote->call('core.deleteMedia', ['media' => $id]); 914 } catch (RemoteException $e) { 915 } 916 $this->assertInstanceOf(RemoteException::class, $e); 917 $this->assertEquals(221, $e->getCode(), 'Non existing media id given'); 918 } 919 // endregion 920} 921